Git Product home page Git Product logo

pycoast's Introduction

This is the sandbox area for the pytroll project, an international cooperation 
on a future distributed real-time processing system for Meteorological Satellite
Data.



------------------------------------
December 2010

Lars Ørum Rasmussen, Esben Sigård Nielsen, Kristian Rune Larsen, 
Martin Raspaud, Anna Geidne, Adam Dybbroe.

Danish Meteorological Institute (DMI)
Swedish Meteorological and Hydrological Institute (SMHI)

pycoast's People

Contributors

adybbroe avatar avalentino avatar dependabot[bot] avatar djhoese avatar lobsiger avatar loreclem avatar mitkin avatar mraspaud avatar pnuu avatar pre-commit-ci[bot] avatar sebastic avatar thorsteinssonh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pycoast's Issues

inconsitency adding lat labelling on the right (on graticules)...

Code Sample, a minimal, complete, and verifiable piece of code

# Your code here
font=aggdraw.Font('yellow','/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf', opacity = 200, size=30)
areaid = 'eurol'
#areaid = 'germ'
lscn = scn.resample(areaid, radius_of_influence=10000)

lscn.save_dataset(composite, imgdir + '/Metop-A.jpg',
                          overlay={'coast_dir': '/satpy/coastlines/', 'color': (255, 255, 0), 'width': 1.0, 'resolution': 'i',
                          'grid': {'major_lonlat': (10, 10), 'minor_lonlat':(2, 2),'font': font,
                          'write_text': True,
                          'outline': (224, 224, 0), 'outline_opacity': 175,
                          'width': 1.0, 'minor_width':0.5, 'minor_outline_opacity': 175, 'minor_is_tick': False, 'lon_placement':'tb', 'lat_placement': 'lr'}}, fill_value=0)

Problem description

There seems to be some strange inconsitency adding lon/lat labeling in satpy.
If I try to place the labeling with
'lon_placement':'tb', 'lat_placement': 'lr'
and area = eurol
Pic1-Metop-A-1

the '20N' lable is missing on the lower right corner

If I set e.g.
area = germ

the lat label '50N' is missing on the right. I can't get a labeling on the right (pic2)
I even tried to set ''lat_placement': 'lr' " or 'lat_placement': 'r'. But no labeling on the right.

Pic2-Metop-A

Another example, 40N, 50N and 60N missing, 'lat_placement': 'lr'

Noaa_20-Orbit_7372-NightTime-20190422-M15-omerc_bb

Versions of Python, package at hand and relevant dependencies

satpy-0.14.1
pycoast-1.2.2
Python 3.6

area_extent unit scale

Code:

from PIL import Image
from pycoast import ContourWriterAGG
img = Image.open('BMNG_clouds_201109181715_areaT2.png')
proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
area_extent = (-3363403.31,-2291879.85,2630596.69,2203620.1)
area_def = (proj4_string, area_extent)
...

Question:

What is the unit scale of the values of area_extent?

Raster images without map projection

Is it possible to add coastlines and borders to the images with lat/lon coordinates, which don't have any specific map projection? For example, adding borders to the composite images from MODIS L1 data.

Add documentation for `add_shapes` method

I added a add_shapes method to the contour writer when I refactored some stuff. Apparently I didn't add any documentation. Here is a copy of a message I prepared for @raghu330:

You can create the writer object then call cw.add_shapes(img, area_def, feature_type, shapes) where feature_type is either 'polygon' or 'line' and shapes is an iterable (list, tuple, generator) of shape objects. You can also add additional keyword arguments which passed to the individual line and polygon drawing methods like outline, width, etc.

The shapes iterable can be created by doing:

import shapefile
s = shapefile.Reader('filename.shp')
shapes = s.shapes()

Projections defined with extents in degrees not handled properly

Projections defined with extents in degrees are not handled properly. For example EPSG:4326 (global lon/lat grid):

from PIL import Image
from pycoast import ContourWriter
cw_ = ContourWriter()
img = Image.new('RGB', (2000, 1000))
adef = ('+init=EPSG:4326', (-180.0, -90.0, 180.0, 90.0))
cw_.add_coastlines(img, adef, resolution='l')
img.show()

Here the extents are interpreted as metric values, thus placing the coastlines as small smudge in the center of the image.

ImageFont.truetype problem

Dear Developers,
I have Ubuntu 20.04
python 3.8.5
pycoast==1.4.0

I followed:
https://github.com/pytroll/pycoast/blob/master/docs/source/graticule.rst

This did work fine:

 img = Image.open(os.path.join(outDir, outFileName))
 cw = ContourWriterAGG('/home/hu-mka/git/cyclonesatpy/cyclonesatpy/dev/shapefiles/')
 font=aggdraw.Font('black', '/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf',opacity=127, size=16)
 cw.add_coastlines(img, areadef, resolution='l', level=4, outline=(255, 0, 0))
 cw.add_grid(img, areadef, (2.0, 2.0), (1.0, 1.0), font, fill='blue',
 outline = 'blue', minor_outline = 'blue')

But if i replace font by:
font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 16)
I get:

TypeError: text() argument 2 must be Font, not FreeTypeFont
Terveisin, Markus

Test suite fails is the `aggdraw` is not available

======================================================================
ERROR: test_add_polygon_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 495, in test_add_polygon_agg
    cw.add_polygon(img, area_def, polygons['REYKJAVIK_ATC'], outline='red', width=2)
TypeError: add_polygon() got an unexpected keyword argument 'width'

======================================================================
ERROR: test_add_shapefile_shapes_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 518, in test_add_shapefile_shapes_agg
    outline='red', width=2)
TypeError: add_shapefile_shapes() got an unexpected keyword argument 'width'

======================================================================
ERROR: test_europe_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 321, in test_europe_agg
    cw.add_rivers(img, area_def, level=5, outline='blue', width=0.5, outline_opacity=127)
TypeError: add_rivers() got an unexpected keyword argument 'width'

======================================================================
ERROR: test_europe_agg_file (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 338, in test_europe_agg_file
    width=0.5, outline_opacity=127)
TypeError: add_rivers_to_file() got an unexpected keyword argument 'width'

======================================================================
ERROR: test_geos_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 357, in test_geos_agg
    cw.add_coastlines(img, (proj4_string, area_extent), resolution='l', width=0.5)
TypeError: add_coastlines() got an unexpected keyword argument 'width'

======================================================================
ERROR: test_grid_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 378, in test_grid_agg
    minor_is_tick=False)
TypeError: add_grid() got an unexpected keyword argument 'outline_opacity'

======================================================================
ERROR: test_grid_agg_file (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 440, in test_grid_agg_file
    minor_is_tick=False)
TypeError: add_grid_to_file() got an unexpected keyword argument 'outline_opacity'

======================================================================
ERROR: test_grid_agg_txt (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 384, in test_grid_agg_txt
    import aggdraw
ImportError: No module named aggdraw

======================================================================
ERROR: test_grid_nh_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 447, in test_grid_nh_agg
    import aggdraw
ImportError: No module named aggdraw

======================================================================
FAIL: test_dateline_boundary_cross (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 227, in test_dateline_boundary_cross
    self.failUnless(fft_metric(dl_data, res), 'Writing of dateline boundary crossing data failed')
AssertionError: Writing of dateline boundary crossing data failed

======================================================================
FAIL: test_dateline_cross (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 206, in test_dateline_cross
    self.failUnless(fft_metric(dl_data, res), 'Writing of dateline crossing data failed')
AssertionError: Writing of dateline crossing data failed

======================================================================
FAIL: test_grid (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 151, in test_grid
    self.failUnless(fft_metric(grid_data, res), 'Writing of grid failed')
AssertionError: Writing of grid failed

======================================================================
FAIL: test_grid_file (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 185, in test_grid_file
    self.failUnless(fft_metric(grid_data, res), 'Writing of grid failed')
AssertionError: Writing of grid failed

======================================================================
FAIL: test_grid_nh (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 247, in test_grid_nh
    self.failUnless(fft_metric(grid_data, res), 'Writing of nh grid failed')
AssertionError: Writing of nh grid failed

======================================================================
FAIL: test_grid_geos_agg (pycoast.tests.test_pycoast.TestPILAGG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/antonio/debian/git/build-area/pycoast-0.5.4/pycoast/tests/test_pycoast.py", line 422, in test_grid_geos_agg
    self.failUnless(fft_metric(geos_data, res), 'Writing of geos contours failed')
AssertionError: Writing of geos contours failed

----------------------------------------------------------------------
Ran 21 tests in 14.014s

FAILED (failures=6, errors=9)

Segmentation fault if providing font in grid via aggdraw and add_overlay_from_dict to save.dataset...

Code Sample, a minimal, complete, and verifiable piece of code

font = aggdraw.Font('blue','/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
                    opacity=127, size = 40)
coast = {'coast_dir': '/home/test/software/',
         'color': (0, 0, 0), 'width': 1.5, 'resolution': 'i'}
grid  = {'grid': {'major_lonlat': (10,10), 'minor_lonlat': (2, 2),
        'outline': (255, 255, 0) , 'outline_opacity': 175,
        'width': 1.0, 'minor_width': 0.5, 'minor_is_tick': 1,
        'write_text': True, 'lat_placement': 'lr', 'lon_placement': 'b',
        'font': font}}
deco = [{'text': {'txt': 'MSG4', 
         'font': '/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf',
         'font_size': 20, 'height': 10, 'bg': 'white', 'bg_opacity': 127, 'line': 'black'}}]
        
new_scene.save_dataset(composite, imgdir + 'MSG-4.jpg', 
                       overlay = {**coast, **grid},
                       decorate = {'decorate': deco}, fill_value=0)

Problem description

Providing a font with color, type, opacity, and fontsize via aggdraw for grid used in save.dataset via add_overlay_from_dict throws a segmantation fault.

[INFO: 2020-05-25 17:32:26 : satpy.writers] Add coastlines and political borders to image.
Segmentation fault 

This works,

coast = {'coast_dir': '/home/test/software/',
         'color': (0, 0, 0), 'width': 1.5, 'resolution': 'i'}
grid  = {'grid': {'major_lonlat': (10,10), 'minor_lonlat': (2, 2),
        'outline': (255, 255, 0) , 'outline_opacity': 175,
        'width': 1.0, 'minor_width': 0.5, 'minor_is_tick': 1,
        'write_text': True, 'lat_placement': 'lr', 'lon_placement': 'b',                       
        'font': '/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf', 
        'font_size': 40, 'outline': 'blue'}}
deco = [{'text': {'txt': 'MSG4', 
         'font': '/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf',
         'font_size': 20, 'height': 10, 'bg': 'white', 'bg_opacity': 127, 'line': 'black'}}]
                       
new_scene.save_dataset(composite, imgdir + 'MSG-4.jpg', 
                       overlay = {**coast, **grid},
                       decorate = {'decorate': deco}, fill_value=0)

...but in

pycoast/pycoast/cw_base.py

Lines 863 to 869 in 59e981f

if isinstance(font, str):
if is_agg:
from aggdraw import Font
font = Font(outline, font, size=font_size)
else:
from PIL.ImageFont import truetype
font = truetype(font, font_size)

there seems to be a problem setting the opacity (not take into account?) and the font color for the grid labels seems to be the same as for the grid lines (outline)? So I'm not able to provide a different color for the grid lines and the grid lables any more. This was possible before (see font attributes providing via aggdraw) which seems now broken)?

Versions of Python, package at hand and relevant dependencies

aggdraw 1.3.11
pycoast 1.10.3+413.ga5996ec4
satpy 0.10.1.dev2650+gaedf4075
python 3.7
Linux version 4.9.0-9-amd64

Wrongly positioned coastlines on near sided perspective projection

It seems as if coastlines are positioned wrongly on a near sided perspective projection area.

Test code:

import os.path
from pycoast import ContourWriterAGG
from PIL import Image
from mpop.projector import get_area_def
import sys

imgfile = sys.argv[1]
areaid = sys.argv[2]
area_def = get_area_def(areaid)
img = Image.open(imgfile)
cw_ = ContourWriterAGG('/home/a000680/data/shapes')
cw_.add_coastlines(img, area_def)  # , resolution='l', level=4)
img.save(os.path.basename(imgfile).split('.png')[0] + '_overlay.png')

I run it like this:

python add_overlay.py composite_20170527_true_color_land_and_sea_nsper_scand.png nsper_scand

The area definition for nsper_scand is as follows:

REGION: nsper_scand {
        NAME:           nsper_scand
        PCS_ID:         nsper
        PCS_DEF:        proj=nsper,lon_0=16,lat_0=58,h=360000000
        XSIZE:          2000
        YSIZE:          2000
        AREA_EXTENT:    (-3000000, -3000000, 3000000, 3000000)
};

composite_20170527_true_color_land_and_sea_nsper_scand_overlay_thumb

distorted/strange coastlines with pyproj-2.4.2

Code Sample:

from PIL import Image
from pycoast import ContourWriterAGG
from pyresample.geometry import AreaDefinition
img = Image.new('RGB', (425, 425))
area_def = AreaDefinition('my_area', 'Area Description', 'geos_proj',
     {'proj': 'geos', 'lon_0': 0.0, 'a': 6378169.00, 'b': 6356583.80, 'h': 35785831.0},
     425, 425,
     (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612))
cw = ContourWriterAGG('/home/cpeters/satpy/shapes')
cw.add_coastlines(img, area_def, resolution='l')
img.save('/mnt/nfs/rumo/test.png')

Problem description:

coastlines are strange and distorted if using pyproj-2.4.2, version 2.4.1 and lower working well

Actual Result (pyproj-2.4.2):
test-1

Versions:
pyproj-2.4.2.post1
pycoast-1.3.1

pycoast compatability issue with pyproj 2+

when running the following on a resampled scene
scn.show('overview', overlay={'coast_dir': ' /tcenas/proj/mpef/pytroll_training/data/shapes/', 'color': (255, 0, 0), 'resolution': 'i'}) i got the following error

    img = get_enhanced_image(self[dataset_id].squeeze(), overlay=overlay)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/satpy/writers/__init__.py", line 450, in get_enhanced_image
    img = add_overlay(img, dataset.attrs['area'], fill_value=fill_value, **overlay)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/satpy/writers/__init__.py", line 267, in add_overlay
    resolution=resolution, width=width, level=level_coast)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/pycoast/cw_agg.py", line 414, in add_coastlines
    y_offset=y_offset)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/pycoast/cw_base.py", line 591, in _add_feature
    x_offset=x_offset, y_offset=y_offset, **kwargs)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/pycoast/cw_base.py", line 518, in add_shapes
    lon_min, lon_max, lat_min, lat_max = _get_lon_lat_bounding_box(area_extent, x_size, y_size, prj)
  File "/tcenas/home/cduff/miniconda3/envs/satpyEnv/lib/python3.7/site-packages/pycoast/cw_base.py", line 880, in _get_lon_lat_bounding_box
    if prj.is_latlong():
AttributeError: 'Proj' object has no attribute 'is_latlong' ```

i was using the latest version of satpy 0.16.1 and pypropj 2.2.1.

Slack message was posted and a suggestion to downgrade to pyproj 1+ as David Hoese believes there is a compatability issue with pycost and pyproj2


 


Test is not supported for ppc64le (power) architecture

Code Sample, a minimal, complete, and verifiable piece of code

test failing for the below on power arch

coverage run --source=pycoast setup.py test

Problem description

Test is failing for power arch when we try to port power cpu arch support on this package,build is completed sucessfully and facing issue at test only.

Reason for build and test :-
I am working for IBM to port cpu arch ppc64le for open sources.This helps us simplify testing later when distributions are re-building and re-releasing,We typically build applications for customers and ISVs, and while we don't use this package directly,we do count on all of the packages in debian/ubuntu to build other packages. So we more likely have this as a second or third level dependency and couldn't tell you explicitly which features we use or our usage model.

Expected Output

should comple test test just like amd64

Actual Result, Traceback if applicable

pls refer https://travis-ci.com/github/asellappen/pycoast/jobs/457849733

======================================================================
FAIL: test_grid_germ (pycoast.tests.test_pycoast.TestPIL)
Check that issue #26 is fixed.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/asellappen/pycoast/pycoast/tests/test_pycoast.py", line 199, in test_grid_germ
    self.assertTrue(fft_metric(grid_data, res), 'Writing of grid to germ failed')
AssertionError: False is not true : Writing of grid to germ failed

Details of complete log a thttps://travis-ci.com/github/asellappen/pycoast/jobs/457849733

Versions of Python, package at hand and relevant dependencies

PYTHON_VERSION=3.7 and its failing for all python version configured on travis job.

Thank you for reporting an issue !

Feature request: API to download GSHHS

Add/fix documentation and examples about using pyresample AreaDefs

Code Sample, a minimal, complete, and verifiable piece of code

# Your code here
>>> from PIL import Image
>>> from pycoast import ContourWriterAGG
>>> img = Image.new('RGB', (425, 425))
>>> proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0'
>>> area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612)
>>> area_def = (proj4_string, area_extent)
>>> cw = ContourWriterAGG('/home/esn/data/gshhs')
>>> cw.add_coastlines(img, (proj4_string, area_extent), resolution='l', width=0.5)
>>> img.show()

Problem description

This code could be shown with using AreaDefinitions from pyresample instead of just the proj4_string and the extent. The possibility is mention in one sentence in the middle of the Usage page, it should be made more visible.

Test failures with pyshp 2.0.0

Problem description

pycoast 1.0.0 fails to build with pyshp 2.0.0 due to test failures:

======================================================================
ERROR: test_dateline_boundary_cross (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 254, in test_dateline_boundary_cross
    lon_placement='b', lat_placement='lr')
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

======================================================================
ERROR: test_dateline_cross (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 228, in test_dateline_cross
    lon_placement='b', lat_placement='lr')
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

======================================================================
ERROR: test_grid (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 161, in test_grid
    outline='blue', minor_outline='blue')
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

======================================================================
ERROR: test_grid_file (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 203, in test_grid_file
    outline='blue', minor_outline='blue')
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 289, in add_grid_to_file
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

======================================================================
ERROR: test_grid_geos (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 180, in test_grid_geos
    write_text=False)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

======================================================================
ERROR: test_grid_nh (pycoast.tests.test_pycoast.TestPIL)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/pycoast-1.0.0+dfsg/pycoast/tests/test_pycoast.py", line 279, in test_grid_nh
    lon_placement='tblr', lat_placement='')
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_pil.py", line 254, in add_grid
    lon_placement=lon_placement, lat_placement=lat_placement)
  File "/build/pycoast-1.0.0+dfsg/pycoast/cw_base.py", line 255, in _add_grid
    tmpshape = shapefile.Writer("")
  File "/usr/lib/python2.7/dist-packages/shapefile.py", line 1030, in __init__
    raise Exception('Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.')
Exception: Either the target filepath, or any of shp, shx, or dbf must be set to create a shapefile.

----------------------------------------------------------------------
Ran 11 tests in 14.555s

FAILED (errors=6, skipped=1)

Refer to the pyshp changelog for possible causes:

https://github.com/GeospatialPython/pyshp/tree/2.0.0#200

Additional text overlay options

Suggested improvements to text overlays:

  • Overlays can be specified using points and/or text (and you can easily add other names if you want more), so that you can specify different rendering attributes for each set of points/text
  • The symbol can be None (you need to set ptsize=0 if you don't want a gap) so you can have a pure text overlay
  • Coordinates can be specified in 'pixel' space or 'lonlat' space (the default is lonlat) by giving an additional key in the tuple ((100,50), "my text", "pixel") Negative coords go from right/bottom.

Can pycoast create land/water masks?

Can pycoast be used to create landmasks?
It seems that the task of adding boundaries is much the same as creating a mask but I see no examples demonstrating this usage.

Easy creation of landmasks using this tool would be useful for my processing and likely many others.
I even came across this old issue on pyspectral mentioning the same.

What changes would be needed to allow pycoast to create masks?

add_grid color and font handling is confusing

I was working on a code example to show how the fill keyword argument on add_grid doesn't do anything (which it doesn't), but I couldn't even get an example to work without it being obvious why it didn't work. Let me explain:

  1. fill is actually not used anywhere from add_grid as far as I can tell.
  2. If font is None it fails:

pycoast/pycoast/cw_base.py

Lines 121 to 123 in c9584be

if font is None:
# NOTE: Default font does not use font size in PIL writer
font = self._get_font(kwargs.get('outline', 'black'), font, 12)

This code makes very little sense as we just checked if font is None and then we use it. For the AGG writer this is expected to be the path to the font file...but if we provide a font file path then it doesn't get used because we only create the font object if it is None!?!? 😕

So then you, the user, think "oh I'll just provide a font object", well at that point you aren't using the font size or the fill because aggdraw Fonts have to have the color defined when they are created.

from PIL import Image
import numpy as np
from pycoast import ContourWriterAGG
from pyresample.geometry import AreaDefinition

area_def = AreaDefinition('test', 'test', 'test', {'ellps': 'GRS80', 'h': '35786023', 'lon_0': '-75', 'proj': 'geos', 'units': 'm'}, 1000, 1000, area_extent=(-3600000, -3600000, 3600000, 3600000))

data = np.zeros((1000, 1000, 3), dtype=np.uint8)
img = Image.fromarray(data)
cw = ContourWriterAGG('/data/gshhg_shapefiles')
cw.add_grid(img, area_def, (5, 5), (1, 1), font=aggdraw.Font('green', '/home/davidh/repos/git/pydecorate/pydecorate/fonts/DejaVuSerif.ttf'), outline='red', fill='blue', width=10)
img.save('test.png')

test

So...this needs to be improved. This is confusing to say the least.

Suspected memory leak. Odd behavior when adding overlay to image.

When processing multiple VIIRS composites, I've noticed that memory usage (Maximum resident set size) goes up greatly when adding overlay to images. In my case it is almost doubling from 6.8GB to 11.6GB when adding overlay is the only change.
In addition the memory goes up by each composited where overlay is added instead of spiking for certain amount of time which suggests some resources are not released.

My python environment:
aggdraw (1.3.11)
appdirs (1.4.3)
asciitree (0.3.3)
certifi (2020.4.5.1)
chardet (3.0.4)
configobj (5.0.6)
dask (2.14.0)
docutils (0.16)
fasteners (0.15)
h5py (2.10.0)
idna (2.9)
monotonic (1.5)
numcodecs (0.6.4)
numpy (1.18.2)
pandas (1.0.3)
Pillow (7.1.1)
pip (9.0.1)
pkg-resources (0.0.0)
pycoast (1.3.2)
pykdtree (1.3.1)
pyorbital (1.5.0)
pyproj (2.6.0)
pyresample (1.15.0)
pyshp (2.1.0)
pyspectral (0.9.5)
python-dateutil (2.8.1)
python-geotiepoints (1.1.8)
pytz (2019.3)
PyYAML (5.3.1)
rabbitlistener (0.1)
requests (2.23.0)
satpy (0.21.0)
scipy (1.4.1)
setuptools (39.0.1)
six (1.14.0)
toolz (0.10.0)
trollimage (1.12.0)
trollsift (0.3.4)
urllib3 (1.25.8)
xarray (0.15.1)
zarr (2.4.0)

Test failure on debian sid

Code Sample, a minimal, complete, and verifiable piece of code

$ python3.9 -m pytest pycoast/tests

Problem description

Test failures on debian sid.
Python 3.9
PyCoast 1.5.0
Pyresample 1.21.1
PIL 8.3.2
numpy 1.19.5
aggdraw 1.3.12
pyproj 3.2.1
pyshp 2.1.3

Expected Output

All tests pass.

Actual Result, Traceback if applicable

============================= test session starts ==============================
platform linux -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
rootdir: /build/pycoast-1.5.0+dfsg
collected 33 items

../../../pycoast/tests/test_pycoast.py F.s.F............s............... [100%]

=================================== FAILURES ===================================
_________________________ TestPIL.test_add_points_pil __________________________

self = <pycoast.tests.test_pycoast.TestPIL testMethod=test_add_points_pil>

    def test_add_points_pil(self):
        from pycoast import ContourWriterPIL
        from pyresample.geometry import AreaDefinition
    
        font_file = os.path.join(os.path.dirname(__file__), 'test_data',
                                 'DejaVuSerif.ttf')
        grid_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'nh_points_pil.png'))
        grid_data = np.array(grid_img)
    
        img = Image.new('RGB', (1024, 1024), (255, 255, 255))
    
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625,
                       5326849.0625, 5326849.0625)
    
        area_def = AreaDefinition('nh', 'nh', 'nh', proj4_string,
                                  1024, 1024, area_extent)
    
        cw = ContourWriterPIL(gshhs_root_dir)
        cw.add_coastlines(img, area_def, outline='black', resolution='l',
                          level=4)
        cw.add_borders(img, area_def, outline='black', level=1,
                       resolution='c')
    
        points_list = [((13.4050, 52.5200), 'Berlin')]
        cw.add_points(img, area_def, points_list=points_list, font_file=font_file,
                      symbol='asterisk', ptsize=6, outline='red',
                      box_outline='black')
    
        points_list = [((12.4964, 41.9028), 'Rome')]
        cw.add_points(img, area_def, points_list=points_list, font_file=font_file,
                      symbol='square', ptsize=6, outline='blue', fill='yellow',
                      box_outline='black')
    
        res = np.array(img)
>       self.assertTrue(fft_metric(grid_data, res),
                        'Writing of nh points failed')
E       AssertionError: False is not true : Writing of nh points failed

../../../pycoast/tests/test_pycoast.py:392: AssertionError
------------------------------ Captured log call -------------------------------
WARNING  pycoast.cw_pil:cw_pil.py:67 Box background will not be added; please use ContourWriterAGG module
WARNING  pycoast.cw_pil:cw_pil.py:67 Box background will not be added; please use ContourWriterAGG module
_______________ TestPIL.test_config_file_points_and_borders_pil ________________

self = <pycoast.tests.test_pycoast.TestPIL testMethod=test_config_file_points_and_borders_pil>

    def test_config_file_points_and_borders_pil(self):
        from pycoast import ContourWriterPIL
        from pyresample.geometry import AreaDefinition
    
        config_file = os.path.join(os.path.dirname(__file__),
                                   'nh_points_pil.ini')
    
        grid_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'nh_points_cfg_pil.png'))
        grid_data = np.array(grid_img)
    
        img = Image.new('RGB', (1024, 1024), (255, 255, 255))
    
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625,
                       5326849.0625, 5326849.0625)
    
        area_def = AreaDefinition('nh', 'nh', 'nh', proj4_string,
                                  1024, 1024, area_extent)
    
        cw = ContourWriterPIL(gshhs_root_dir)
    
        cw.add_overlay_from_config(config_file, area_def, img)
    
        res = np.array(img)
>       self.assertTrue(fft_metric(grid_data, res),
                        'Writing of nh points failed')
E       AssertionError: False is not true : Writing of nh points failed

../../../pycoast/tests/test_pycoast.py:476: AssertionError
------------------------------ Captured log call -------------------------------
WARNING  pycoast.cw_pil:cw_pil.py:67 Box background will not be added; please use ContourWriterAGG module
WARNING  pycoast.cw_pil:cw_pil.py:67 Box background will not be added; please use ContourWriterAGG module
=============================== warnings summary ===============================
pycoast/tests/test_pycoast.py::TestPIL::test_add_points_pil
  /usr/lib/python3/dist-packages/pyresample/bilinear/__init__.py:49: UserWarning: XArray and/or zarr not found, XArrayBilinearResampler won't be available.
    warnings.warn("XArray and/or zarr not found, XArrayBilinearResampler won't be available.")

pycoast/tests/test_pycoast.py::TestPIL::test_add_points_pil
pycoast/tests/test_pycoast.py::TestPIL::test_add_points_pil
pycoast/tests/test_pycoast.py::TestPIL::test_config_file_points_and_borders_pil
pycoast/tests/test_pycoast.py::TestPIL::test_config_file_points_and_borders_pil
pycoast/tests/test_pycoast.py::TestPILAGG::test_add_points_agg
pycoast/tests/test_pycoast.py::TestPILAGG::test_add_points_agg
pycoast/tests/test_pycoast.py::TestPILAGG::test_config_file_points_and_borders_agg
pycoast/tests/test_pycoast.py::TestPILAGG::test_config_file_points_and_borders_agg
  /usr/lib/python3/dist-packages/pyresample/geometry.py:1921: DeprecationWarning: 'get_xy_from_lonlat' is deprecated, please use 'get_array_indices_from_lonlat' instead.
    warnings.warn("'get_xy_from_lonlat' is deprecated, please use "

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ============================
FAILED ../../../pycoast/tests/test_pycoast.py::TestPIL::test_add_points_pil
FAILED ../../../pycoast/tests/test_pycoast.py::TestPIL::test_config_file_points_and_borders_pil
============= 2 failed, 29 passed, 2 skipped, 9 warnings in 43.01s =============

Versions of Python, package at hand and relevant dependencies

Thank you for reporting an issue !

Cached overlays are pale

Problem description

Cached overlay outline and fill colors are pale. See this thread:

https://groups.google.com/g/pytroll/c/7VVgsmstLkQ

@djhoese for unknown reason the google list deletes all my posts. I found out that the pycoast stored overlay.png
is already pale. I made a composite with a clean image of Switzerland and the stored overlay file using ImageMagick.
I get exactly the Satpy result for cached overlays. You can see with the bare eye that the cached overlay.png is pale.

Switzerland-overlay

import ImageDraw incompatible with Pillow

What steps will reproduce the problem?
1. Install Pillow (https://pypi.python.org/pypi/Pillow/2.2.2) instead of PIL
2. import pycoast (results in ImportError)

What is the expected output? What do you see instead?
Most things are compatible between PIL and Pillow, but the "import ImageDraw" 
doesn't work with Pillow. 

What version of the product are you using? On what operating system?
Installed pycoast 0.5.2 on my mac 10.9 in a virtualenv with Pillow installed 
with macports.

I prefer using Pillow instead of PIL. It seems to work for me if you use "from 
PIL import ImageDraw" with both PIL and Pillow. Thoughts? Thanks.

Original issue reported on code.google.com by [email protected] on 18 Dec 2013 at 7:54

add_coastlines call is incorrect in documentation

Problem description

The add_coastlines call given on this page of the documentation is incorrect:
cw.add_coastlines(img, (proj4_string, area_extent), resolution='l', width=0.5)
Should be
cw.add_coastlines(img, area_extent, resolution='l', width=0.5)

Test failure with Pillow 9.4

Code Sample, a minimal, complete, and verifiable piece of code

$ python3 -m pytest -k test_grid_germ

Problem description

After the update of Pillow to v9.4 (from v9.3) one of the tests fails.
The test has been detected on debian/sid but it is also reproducible in conda environments.
This issue seems not to be related to #57 because the output of the textsize function seems to be the same before and after the update to the new Pillow version.

txt_width, txt_height = draw.textsize(txt, font)

See also: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1028040

Expected Output

All tests pass.

Actual Result, Traceback if applicable

========================================================== test session starts ===========================================================
platform linux -- Python 3.11.1, pytest-7.2.0, pluggy-1.0.0+repack
rootdir: /home/antonio/debian/git/pycoast
plugins: hypothesis-6.61.0, arraydiff-0.5.0, astropy-0.10.0, mock-3.8.2, lazy-fixture-0.6.3, doctestplus-0.12.1, openfiles-0.5.0, filter-subpackage-0.1.2, remotedata-0.4.0, cov-4.0.0, astropy-header-0.2.2
collected 57 items / 56 deselected / 1 selected                                                                                          

pycoast/tests/test_pycoast.py F                                                                                                    [100%]

================================================================ FAILURES ================================================================
__________________________________________________ TestContourWriterPIL.test_grid_germ ___________________________________________________

self = <pycoast.tests.test_pycoast.TestContourWriterPIL object at 0x7f01782c6cd0>

    def test_grid_germ(self):
        """Check that issue #26 is fixed."""
        from pycoast import ContourWriterPIL
    
        result_file = os.path.join(os.path.dirname(__file__), "grid_germ.png")
        grid_img = Image.open(result_file)
        grid_data = np.array(grid_img)
        img = Image.new("RGB", (1024, 1024))
        proj4_string = "+proj=stere +ellps=bessel +lat_0=90.0 +lon_0=5.0 +lat_ts=50.0 +a=6378144.0 +b=6356759.0"
        area_extent = [-155100.436345, -4441495.37946, 868899.563655, -3417495.37946]
    
        area_def = (proj4_string, area_extent)
    
        cw = ContourWriterPIL(gshhs_root_dir)
    
        cw.add_coastlines(img, area_def, resolution="l", level=4)
        font = ImageFont.truetype(os.path.join(os.path.dirname(__file__), "test_data", "DejaVuSerif.ttf"), 16)
        cw.add_grid(
            img,
            area_def,
            (10.0, 10.0),
            (2.0, 2.0),
            font=font,
            fill="yellow",
            write_text=True,
            outline="red",
            minor_outline="white",
        )
    
        res = np.array(img)
>       assert fft_metric(grid_data, res), "Writing of grid to germ failed"
E       AssertionError: Writing of grid to germ failed
E       assert False
E        +  where False = fft_metric(array([[[0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        ...,\n        [0, 0, 0],\n        [0, 0, 0],\n        [0...     [0, 0, 0],\n        [0, 0, 0],\n        ...,\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0]]], dtype=uint8), array([[[0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        ...,\n        [0, 0, 0],\n        [0, 0, 0],\n        [0...     [0, 0, 0],\n        [0, 0, 0],\n        ...,\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0]]], dtype=uint8))

pycoast/tests/test_pycoast.py:214: AssertionError
============================================================ warnings summary ============================================================
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ
  /home/antonio/debian/git/pycoast/pycoast/cw_base.py:170: DeprecationWarning: textsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use textbbox or textlength instead.
    txt_width, txt_height = draw.textsize(txt, font)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================================== short test summary info =========================================================
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ - AssertionError: Writing of grid to germ failed
============================================== 1 failed, 56 deselected, 4 warnings in 3.71s ==============================================

Versions of Python, package at hand and relevant dependencies

Python 3.11
Pillow 9.4

Incompatibility with Pillow 10

Code Sample, a minimal, complete, and verifiable piece of code

$ python3 -m pytest

Problem description

Unit test failure when Pillo 10 is isntalled

Expected Output

All tests pass successfully

Actual Result, Traceback if applicable

$ python3 -m pytest -v
================================================================== test session starts ==================================================================
platform linux -- Python 3.11.4, pytest-7.4.0, pluggy-1.0.0+repack -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/antonio/debian/git/pycoast
plugins: mock-3.11.1, vcr-1.0.2
collected 57 items                                                                                                                                      

pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_europe PASSED                                                                           [  1%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_europe_file PASSED                                                                      [  3%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_geos PASSED                                                                             [  5%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid PASSED                                                                             [  7%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ FAILED                                                                        [  8%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_geos PASSED                                                                        [ 10%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_geos_with_text PASSED                                                              [ 12%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_file PASSED                                                                        [ 14%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_dateline_cross PASSED                                                                   [ 15%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_dateline_boundary_cross PASSED                                                          [ 17%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_nh PASSED                                                                          [ 19%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_polygon PASSED                                                                      [ 21%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_pil FAILED                                                                   [ 22%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_coordinate_conversion FAILED                                                 [ 24%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_bad_image_coords PASSED                                                      [ 26%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_bad_coord_ref PASSED                                                         [ 28%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_shapefile_shapes SKIPPED (dataset not available: test_data/shapes/Metareas.shp)     [ 29%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_config_file_coasts_and_grid PASSED                                                      [ 31%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_config_file_points_and_borders_pil FAILED                                               [ 33%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_pil FAILED                                                                   [ 35%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_cfg_pil FAILED                                                               [ 36%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_from_dict_pil FAILED                                                         [ 38%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_shapefiles_from_dict_pil FAILED                                                     [ 40%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_one_shapefile_from_cfg_pil FAILED                                                   [ 42%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_grid_from_dict_pil FAILED                                                           [ 43%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_western_shapes_pil FAILED                                                               [ 45%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_eastern_shapes_pil FAILED                                                               [ 47%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_no_h_scratch_pil FAILED                                                                 [ 49%]
pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_no_v_scratch_pil FAILED                                                                 [ 50%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_europe_agg PASSED                                                                    [ 52%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_europe_agg_file PASSED                                                               [ 54%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_geos_agg PASSED                                                                      [ 56%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_grid_agg PASSED                                                                      [ 57%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_grid_agg_txt PASSED                                                                  [ 59%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_grid_geos_agg PASSED                                                                 [ 61%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_grid_agg_file PASSED                                                                 [ 63%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_grid_nh_agg PASSED                                                                   [ 64%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_polygon_agg PASSED                                                               [ 66%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_points_agg PASSED                                                                [ 68%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_shapefile_shapes_agg SKIPPED (dataset not available: test_data/shapes/Metare...) [ 70%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_config_file_coasts_and_grid PASSED                                                   [ 71%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_config_file_points_and_borders_agg PASSED                                            [ 73%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_coastlines_convert_to_rgba_agg PASSED                                                [ 75%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_cities_agg PASSED                                                                [ 77%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_cities_cfg_agg PASSED                                                            [ 78%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_cities_from_dict_agg PASSED                                                      [ 80%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_shapefiles_from_dict_agg FAILED                                                  [ 82%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_one_shapefile_from_cfg_agg FAILED                                                [ 84%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_grid_from_dict_agg PASSED                                                        [ 85%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_western_shapes_agg PASSED                                                            [ 87%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_eastern_shapes_agg PASSED                                                            [ 89%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_no_h_scratch_agg PASSED                                                              [ 91%]
pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_no_v_scratch_agg PASSED                                                              [ 92%]
pycoast/tests/test_pycoast.py::TestFromConfig::test_foreground PASSED                                                                             [ 94%]
pycoast/tests/test_pycoast.py::TestFromConfig::test_cache FAILED                                                                                  [ 96%]
pycoast/tests/test_pycoast.py::TestFromConfig::test_caching_with_param_changes FAILED                                                             [ 98%]
pycoast/tests/test_pycoast.py::TestFromConfig::test_get_resolution PASSED                                                                         [100%]

======================================================================= FAILURES ========================================================================
__________________________________________________________ TestContourWriterPIL.test_grid_germ __________________________________________________________

self = <pycoast.tests.test_pycoast.TestContourWriterPIL object at 0x7f2cc6930210>

    def test_grid_germ(self):
        """Check that issue #26 is fixed."""
        from pycoast import ContourWriterPIL
    
        result_file = os.path.join(os.path.dirname(__file__), "grid_germ.png")
        grid_img = Image.open(result_file)
        grid_data = np.array(grid_img)
        img = Image.new("RGB", (1024, 1024))
        proj4_string = "+proj=stere +ellps=bessel +lat_0=90.0 +lon_0=5.0 +lat_ts=50.0 +a=6378144.0 +b=6356759.0"
        area_extent = [-155100.436345, -4441495.37946, 868899.563655, -3417495.37946]
    
        area_def = (proj4_string, area_extent)
    
        cw = ContourWriterPIL(gshhs_root_dir)
    
        cw.add_coastlines(img, area_def, resolution="l", level=4)
        font = ImageFont.truetype(os.path.join(os.path.dirname(__file__), "test_data", "DejaVuSerif.ttf"), 16)
>       cw.add_grid(
            img,
            area_def,
            (10.0, 10.0),
            (2.0, 2.0),
            font=font,
            fill="yellow",
            write_text=True,
            outline="red",
            minor_outline="white",
        )

pycoast/tests/test_pycoast.py:201: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pycoast/cw_pil.py:342: in add_grid
    self._add_grid(
pycoast/cw_base.py:203: in _add_grid
    grid_drawer.draw_grid()
pycoast/cw_base.py:1570: in draw_grid
    self._draw_major_lon_lines()
pycoast/cw_base.py:1630: in _draw_major_lon_lines
    self._draw_major_lines(
pycoast/cw_base.py:1666: in _draw_major_lines
    self._draw_grid_labels(
pycoast/cw_base.py:1719: in _draw_grid_labels
    self._cw._draw_text(draw, xy[0], txt, font, align=xy[1], **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pycoast.cw_pil.ContourWriterPIL object at 0x7f2cc69bcf90>, draw = <PIL.ImageDraw.ImageDraw object at 0x7f2d199030d0>
position = (543.7293441573487, 1020), txt = '10E', font = <PIL.ImageFont.FreeTypeFont object at 0x7f2d19902290>, align = 'CB'
kwargs = {'fill': 'yellow', 'lat_placement': 'lr', 'lon_placement': 'tb', 'minor_is_tick': True, ...}

    def _draw_text(self, draw, position, txt, font, align="cc", **kwargs):
        """Draw text with agg module."""
>       txt_width, txt_height = draw.textsize(txt, font)
E       AttributeError: 'ImageDraw' object has no attribute 'textsize'

pycoast/cw_base.py:170: AttributeError

[CUT]

________________________________________________ TestContourWriterPIL.test_add_shapefiles_from_dict_pil _________________________________________________

self = <pycoast.tests.test_pycoast.TestContourWriterPIL object at 0x7f2cc695b850>

    def test_add_shapefiles_from_dict_pil(self):
        from pyresample.geometry import AreaDefinition
    
        from pycoast import ContourWriterPIL
    
        grid_img = Image.open(os.path.join(os.path.dirname(__file__), "two_shapefiles_pil.png"))
        grid_data = np.array(grid_img)
    
        img = Image.new("RGB", (425, 425))
        proj4_string = "+proj=merc +lon_0=-60 +lat_ts=-30.0 +a=6371228.0 +units=m"
        area_extent = (-2000000.0, -5000000.0, 5000000.0, 2000000.0)
        area_def = AreaDefinition("nh", "nh", "nh", proj4_string, 425, 425, area_extent)
    
        cw = ContourWriterPIL(gshhs_root_dir)
    
        overlays = {}
        overlays["coasts"] = {"level": 4, "resolution": "l"}
        overlays["shapefiles"] = [
            {
                "filename": os.path.join(os.path.dirname(__file__), "test_data/shapes/Metareas.shp"),
                "outline": "magenta",
                "width": 2.5,
            },
            {
                "filename": os.path.join(
                    os.path.dirname(__file__),
                    "test_data/shapes/divisao_politica/BR_Regioes.shp",
                ),
                "outline": "red",
                "fill": "yellow",
                "fill_opacity": 50,
            },
        ]
    
>       img = cw.add_overlay_from_dict(overlays, area_def, background=img)

pycoast/tests/test_pycoast.py:877: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pycoast/cw_base.py:548: in add_overlay_from_dict
    return overlay_helper.apply_overlays()
pycoast/cw_base.py:1245: in apply_overlays
    self._add_shapefiles_from_dict(overlays["shapefiles"])
pycoast/cw_base.py:1309: in _add_shapefiles_from_dict
    self._cw.add_shapefile_shapes(
pycoast/cw_pil.py:152: in add_shapefile_shapes
    self._add_shapefile_shapes(
pycoast/cw_base.py:213: in _add_shapefile_shapes
    sf = shapefile.Reader(filename)
/usr/lib/python3/dist-packages/shapefile.py:1048: in __init__
    self.load(path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <shapefile.Reader object at 0x7f2cc60c54d0>, shapefile = '/home/antonio/debian/git/pycoast/pycoast/tests/test_data/shapes/Metareas.shp'

    def load(self, shapefile=None):
        """Opens a shapefile from a filename or file-like
        object. Normally this method would be called by the
        constructor with the file name as an argument."""
        if shapefile:
            (shapeName, ext) = os.path.splitext(shapefile)
            self.shapeName = shapeName
            self.load_shp(shapeName)
            self.load_shx(shapeName)
            self.load_dbf(shapeName)
            if not (self.shp or self.dbf):
>               raise ShapefileException("Unable to open %s.dbf or %s.shp." % (shapeName, shapeName))
E               shapefile.ShapefileException: Unable to open /home/antonio/debian/git/pycoast/pycoast/tests/test_data/shapes/Metareas.dbf or /home/antonio/debian/git/pycoast/pycoast/tests/test_data/shapes/Metareas.shp.

/usr/lib/python3/dist-packages/shapefile.py:1193: ShapefileException

[CUT]

================================================================ short test summary info ================================================================
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_grid_germ - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_points_coordinate_conversion - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_config_file_points_and_borders_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_cfg_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_cities_from_dict_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_shapefiles_from_dict_pil - shapefile.ShapefileException: Unable to open /home/antonio/debian/git/pycoast/pycoast/tests/test_data/shapes/Metareas.dbf or /home/antonio/debian/gi...
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_one_shapefile_from_cfg_pil - shapefile.ShapefileException: Unable to open pycoast/tests/test_data/shapes/Metareas.dbf or pycoast/tests/test_data/shapes/Metareas.shp.
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_add_grid_from_dict_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_western_shapes_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_eastern_shapes_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_no_h_scratch_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPIL::test_no_v_scratch_pil - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_shapefiles_from_dict_agg - shapefile.ShapefileException: Unable to open /home/antonio/debian/git/pycoast/pycoast/tests/test_data/shapes/Metareas.dbf or /home/antonio/debian/gi...
FAILED pycoast/tests/test_pycoast.py::TestContourWriterPILAGG::test_add_one_shapefile_from_cfg_agg - shapefile.ShapefileException: Unable to open pycoast/tests/test_data/shapes/Metareas.dbf or pycoast/tests/test_data/shapes/Metareas.shp.
FAILED pycoast/tests/test_pycoast.py::TestFromConfig::test_cache - AttributeError: 'ImageDraw' object has no attribute 'textsize'
FAILED pycoast/tests/test_pycoast.py::TestFromConfig::test_caching_with_param_changes - AttributeError: 'ImageDraw' object has no attribute 'textsize'
================================================== 18 failed, 37 passed, 2 skipped in 67.12s (0:01:07) ==================================================

Versions of Python, package at hand and relevant dependencies

  • Python v3.11.4
  • pycoast v1.6.1
  • Pillow v10.0.0

Not compatible with pyproj>=2.2.0

I think is_latlong used here:

https://github.com/pytroll/pycoast/blob/master/pycoast/cw_base.py#L694

is deprecated in pyproj>=2.2.0

Might be other problems similar to this.

If used with pyproj<2.2.0 this message is printed:

/software/pytroll/lib/python3.5/site-packages/pyproj/proj.py:355: UserWarning: 'is_latlong()' is deprecated and will be removed in version 2.2.0. Please use 'crs.is_geographic'.
  "'is_latlong()' is deprecated and will be removed in version 2.2.0. "

Ideas for additional checks for "scratches" or shapfile lines crossing the image

Problem description

There are various cases where due to the nature of shapefiles in lon/lat space and images in various projections' space, that you get drawn lines from shapefiles that go straight across the image. This essentially comes from "point N" of a polygon mapping to the outside left side of the image and "point N +1" mapping to the outside right side of the image and pycoast drawing a line connecting these two points. This often happens because the points straddle the anti-meridian of the target projection or the anti-meridian of the lon/lat space (-180/180) depending on the shapefiles used.

@lobsiger had done some work in the past to minimize the number of these lines in #59 and I think a couple other PRs. I'm starting this issue to talk about other options that weren't implemented yet and I think could easily be added, but may affect performance.

The Code

The main part of the code that would be modified is this method here:

if (x >= 1e30).any() or (y >= 1e30).any():

This line is essentially a boolean mask used to say "is this point valid in this projection" and is used in a later line to determine where to split a polygon into smaller segments to avoid drawing a line from point N to point N+1 where it would draw a large non-real line across the image.

Adding any additional conditions to this should be easy as we can just do a boolean AND or OR with a numpy array.

Possible solutions

My first thought was to take the difference between each coordinate point in the X dimension (the only dimension that has wrapping/non-contiguous coordinates) using np.diff and look for anything larger than the X-extents of the image. I realized later that this could be a problem for very small geographic regions where the points for larger features like country borders and coastlines might be much further apart than looking at a single province or city, even though you'd still want the line to show up.

My next thought was still to do the np.diff but to maybe look for any difference larger than X degrees/meters (depending on the output projection). A good value for this could be determined offline (not at runtime, just store it in a constant) by taking all the GSHHG shapefiles/polygons and determine the largest difference between their points in geocentric meters. This should give a clear indication of "point N is at location A, but point N+1 is at location A+10000000 meters" and work for global images and local (city-level) images. @lobsiger's existing checks should limit polygons that are completely outside the image already, but this will handle the anti-meridian case...I hope.

Thoughts @mraspaud @lobsiger ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.