marceloprates / prettymaps

A small set of Python functions to draw pretty maps from OpenStreetMap data. Based on osmnx, matplotlib and shapely libraries.
GNU Affero General Public License v3.0
11.14k stars 527 forks source link

Coastline Rendering? #7

Open hanksims opened 3 years ago

hanksims commented 3 years ago

I'm sure this is something that you've considered, but how possible is it to render land/ocean using OSM coastline data?

marceloprates commented 3 years ago

I'm not sure, but intend to add support for this in the future. One possible solution is to use the coastline (which is a 1d curve) to split the map's boundary in two polygons, such that one corresponds to the continent and the other to the sea. The latter could be added to the "sea" layer, perhaps. I'll think about it.

hanksims commented 3 years ago

I'm out of my depth, here, but in case this is helpful: Splitting the map cleanly into two and only two polygons might not handle every case. Here's a sample of running my town zoomed-out with the "water" style using the tags 'natural': ['water', 'bay']:

eureka

.. and here's a screenshot of a similar view on OSM ...

OpenStreetMap

You'd think that our bay would be covered with the "bay" tag, there, but it's not -- it's delineated by OSM coastline.

Anyway, thanks for the beautiful software!

erkannt commented 3 years ago

I had success by using 'query features' on the water in the openstreetmap.org web display. In my case the water was part of the English Channel and that is tagged with natural: strait. Added that to my water layer and got this. It did slow the script down quite a bit. The English Channel is quite a massive polygon ^^

image

ushham commented 3 years ago

I am having similar issues, I created a new layer object which I added to the layers dictionary: 'coastline': {'tags': {'natural': 'coastline', 'strait'}}

and

'ocean': {'tags': {'place': ['ocean', 'sea']}},

I got the tag names from here: https://wiki.openstreetmap.org/wiki/Tag:natural%3Dcoastline

You then need to include a line to define the colouring for coastline (I just copied and pasted what was already in the code for water): 'coastline': {'fc': '#a1e3ff', 'ec': '#2F3737', 'lw': 1, 'zorder': 2},

This has helped fill in some areas, but I am still missing some patches that should be covered in water

hanksims commented 3 years ago

For me that inverted things -- islands rendered as ocean:

eureka

roxanidg commented 2 years ago

Did someone solve the sea and ocean issue?

hanksims commented 2 years ago

Yes. See

https://github.com/marceloprates/prettymaps/pull/47

chrstnbwnkl commented 1 year ago

As far as I can tell the functionality to load the coastline from a shapefile introduced in #47 has been removed in #102 . I am still running into problems when trying to plot the ocean correctly in this example:


new_params_default = {'circle': None,
 'layers': {'beach': {'tags': {'natural': 'beach'}},
          #  'building': {'tags': {'building': True, 'landuse': 'construction'}},
            'forest': {'tags': {'landuse': 'forest'}},
            'green': {'tags': {'landuse': ['grass', 'orchard'],
                               'leisure': 'park',
                               'natural': ['island', 'wood']}},
            'parking': {'tags': {'amenity': 'parking',
                                 'highway': 'pedestrian',
                                 'man_made': 'pier'}},
            'perimeter': {},
            'streets': {'width': {'cycleway': 3.5,
                                  'footway': 1,
                                  'motorway': 5,
                                  'pedestrian': 2,
                                  'primary': 4.5,
                                  'residential': 3,
                                  'secondary': 4,
                                  'service': 2,
                                  'tertiary': 3.5,
                                  'trunk': 5,
                                  'unclassified': 2}},
            'water': {'tags': {'natural': ['water', 'bay']}}},
 'radius': 500,
 'style': {'background': {'fc': '#F2F4CB', 'zorder': -1},
           'beach': {'ec': '#2F3737',
                     'fc': '#FCE19C',
                     'hatch': 'ooo...',
                     'hatch_c': '#d4d196',
                     'lw': 1,
                     'zorder': 3},
           'building': {'ec': '#2F3737',
                        'lw': 0.5,
                        'palette': ['#433633', '#FF5E5B'],
                        'zorder': 5},
           'forest': {'ec': '#2F3737', 'fc': '#64B96A', 'lw': 1, 'zorder': 2},
           'green': {'ec': '#2F3737',
                     'fc': '#8BB174',
                     'hatch': 'ooo...',
                     'hatch_c': '#A7C497',
                     'lw': 1,
                     'zorder': 1},
           'parking': {'ec': '#2F3737', 'fc': '#F2F4CB', 'lw': 1, 'zorder': 3},
           'perimeter': {'fill': False, 'lw': 0, 'zorder': 0},
           'streets': {'alpha': 1,
                       'ec': '#475657',
                       'fc': '#2F3737',
                       'lw': 0,
                       'zorder': 4},
           'water': {'ec': '#2F3737',
                     'fc': '#a8e1e6',
                     'hatch': 'ooo...',
                     'hatch_c': '#9bc3d4',
                     'lw': 1,
                     'zorder': 3}}}

prettymaps.create_preset("sf_1", **new_params_default)
plot = prettymaps.plot((37.80868, -122.50402,), radius=6500, preset='sf_1')

Gives me

grafik

Am I missing something?