kopia lustrzana https://github.com/marceloprates/prettymaps
Changed license and README
rodzic
fd97a9bbc2
commit
4a9e2ac7df
20
README.md
20
README.md
|
@ -2,20 +2,18 @@
|
||||||
|
|
||||||
A minimal Python library to draw customized maps from [OpenStreetMap](https://www.openstreetmap.org/#map=12/11.0733/106.3078) created using the [osmnx](https://github.com/gboeing/osmnx), [matplotlib](https://matplotlib.org/), [shapely](https://shapely.readthedocs.io/en/stable/index.html) and [vsketch](https://github.com/abey79/vsketch) libraries.
|
A minimal Python library to draw customized maps from [OpenStreetMap](https://www.openstreetmap.org/#map=12/11.0733/106.3078) created using the [osmnx](https://github.com/gboeing/osmnx), [matplotlib](https://matplotlib.org/), [shapely](https://shapely.readthedocs.io/en/stable/index.html) and [vsketch](https://github.com/abey79/vsketch) libraries.
|
||||||
|
|
||||||
[![CC BY NC 4.0][cc-by-nc-shield]][cc-by-nc]
|
|
||||||
|
|
||||||
This work is [licensed](LICENSE) under a
|
This work is [licensed](LICENSE) under a GNU Affero General Public License v3.0:
|
||||||
[Creative Commons Attribution-NonCommercial 4.0 International][cc-by-nc].
|
- You can make commercial use, distribute and modificate this project, but must **disclose** the source code with the license and copyright notice.
|
||||||
|
|
||||||
[![CC BY 4.0][cc-by-image]][cc-by-nc]
|
Note about NFTs:
|
||||||
|
- I am personally **against** NFTs for their [environmental impact](https://earth.org/nfts-environmental-impact/), the fact that they're a [giant money-laundering pyramid scheme](https://twitter.com/smdiehl/status/1445795667826208770) and the structural incentives they create for [theft](https://twitter.com/NFTtheft) in the open source and generative art communities.
|
||||||
|
- **I do not authorize in any way this project to be used for selling NFTs**, although I have no legal way of enforcing my intent. **Respect the creator**.
|
||||||
|
- The [AeternaCivitas](https://twitter.com/AeternaCivitas) and [geoartnft](twitter.com/geoartnft) projects have used this work to sell NFTs and refused to credit it. See how they reacted after being exposed: [AeternaCivitas](etc/NFT_theft_AeternaCivitas.jpg), [geoartnft](etc/NFT_theft_geoart.jpg).
|
||||||
|
- **I have closed my other generative art projects on Github and won't be sharing new ones as open source to protect me from the NFT community**.
|
||||||
|
|
||||||
[cc-by-nc]: http://creativecommons.org/licenses/by-nc/4.0/
|
Note about crediting:
|
||||||
[cc-by-image]: https://i.creativecommons.org/l/by-nc/4.0/88x31.png
|
- Please keep the printed message on the figures crediting OpenStreetMap and my repository (The OSM credit is [mandatory by their license](https://www.openstreetmap.org/copyright)).
|
||||||
[cc-by-nc-shield]: https://img.shields.io/badge/license-CC%20BY%20NC%204.0-lightgrey.svg
|
|
||||||
|
|
||||||
- **Because of the recent episodes of plagiarism and refusal to credit this project in the NFT Community (Twitter profiles [AeternaCivitas](https://twitter.com/AeternaCivitas) and [geoartnft](twitter.com/geoartnft)) I have decided to change my license to Creative Commons (CC-BY-NC-4.0) which requires you to credit it everytime you use it and forbids you to use if for commercial purposes.**
|
|
||||||
- **The printed message on the figures crediting OpenStreetMap and my repository, included by default, is mandatory.**
|
|
||||||
- **I do not authorize people to sell NFTs using prettymaps and ask that you contact me if you know of someone who is doing it.**
|
|
||||||
- **CREDIT OPEN SOURCE DEVELOPERS!**
|
- **CREDIT OPEN SOURCE DEVELOPERS!**
|
||||||
|
|
||||||
<a href='https://ko-fi.com/marceloprates_' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
<a href='https://ko-fi.com/marceloprates_' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
||||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 168 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 100 KiB |
|
@ -1,168 +0,0 @@
|
||||||
import math
|
|
||||||
|
|
||||||
from matplotlib import text as mtext
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
class CurvedText(mtext.Text):
|
|
||||||
"""
|
|
||||||
A text object that follows an arbitrary curve.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, x, y, text, axes, **kwargs):
|
|
||||||
super(CurvedText, self).__init__(x[0], y[0], " ", **kwargs)
|
|
||||||
|
|
||||||
axes.add_artist(self)
|
|
||||||
|
|
||||||
##saving the curve:
|
|
||||||
self.__x = x
|
|
||||||
self.__y = y
|
|
||||||
self.__zorder = self.get_zorder()
|
|
||||||
|
|
||||||
##creating the text objects
|
|
||||||
self.__Characters = []
|
|
||||||
for c in text:
|
|
||||||
if c == " ":
|
|
||||||
##make this an invisible 'a':
|
|
||||||
t = mtext.Text(0, 0, "a")
|
|
||||||
t.set_alpha(0.0)
|
|
||||||
else:
|
|
||||||
t = mtext.Text(0, 0, c, **kwargs)
|
|
||||||
|
|
||||||
# resetting unnecessary arguments
|
|
||||||
t.set_ha("center")
|
|
||||||
t.set_rotation(0)
|
|
||||||
t.set_zorder(self.__zorder + 1)
|
|
||||||
|
|
||||||
self.__Characters.append((c, t))
|
|
||||||
axes.add_artist(t)
|
|
||||||
|
|
||||||
##overloading some member functions, to assure correct functionality
|
|
||||||
##on update
|
|
||||||
def set_zorder(self, zorder):
|
|
||||||
super(CurvedText, self).set_zorder(zorder)
|
|
||||||
self.__zorder = self.get_zorder()
|
|
||||||
for c, t in self.__Characters:
|
|
||||||
t.set_zorder(self.__zorder + 1)
|
|
||||||
|
|
||||||
def draw(self, renderer, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Overload of the Text.draw() function. Do not do
|
|
||||||
do any drawing, but update the positions and rotation
|
|
||||||
angles of self.__Characters.
|
|
||||||
"""
|
|
||||||
self.update_positions(renderer)
|
|
||||||
|
|
||||||
def update_positions(self, renderer):
|
|
||||||
"""
|
|
||||||
Update positions and rotations of the individual text elements.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# preparations
|
|
||||||
|
|
||||||
##determining the aspect ratio:
|
|
||||||
##from https://stackoverflow.com/a/42014041/2454357
|
|
||||||
|
|
||||||
##data limits
|
|
||||||
xlim = self.axes.get_xlim()
|
|
||||||
ylim = self.axes.get_ylim()
|
|
||||||
## Axis size on figure
|
|
||||||
figW, figH = self.axes.get_figure().get_size_inches()
|
|
||||||
## Ratio of display units
|
|
||||||
_, _, w, h = self.axes.get_position().bounds
|
|
||||||
##final aspect ratio
|
|
||||||
aspect = ((figW * w) / (figH * h)) * (ylim[1] - ylim[0]) / (xlim[1] - xlim[0])
|
|
||||||
|
|
||||||
# points of the curve in figure coordinates:
|
|
||||||
x_fig, y_fig = (
|
|
||||||
np.array(l)
|
|
||||||
for l in zip(
|
|
||||||
*self.axes.transData.transform(
|
|
||||||
[(i, j) for i, j in zip(self.__x, self.__y)]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# point distances in figure coordinates
|
|
||||||
x_fig_dist = x_fig[1:] - x_fig[:-1]
|
|
||||||
y_fig_dist = y_fig[1:] - y_fig[:-1]
|
|
||||||
r_fig_dist = np.sqrt(x_fig_dist ** 2 + y_fig_dist ** 2)
|
|
||||||
|
|
||||||
# arc length in figure coordinates
|
|
||||||
l_fig = np.insert(np.cumsum(r_fig_dist), 0, 0)
|
|
||||||
|
|
||||||
# angles in figure coordinates
|
|
||||||
rads = np.arctan2((y_fig[1:] - y_fig[:-1]), (x_fig[1:] - x_fig[:-1]))
|
|
||||||
degs = np.rad2deg(rads)
|
|
||||||
|
|
||||||
rel_pos = 10
|
|
||||||
for c, t in self.__Characters:
|
|
||||||
# finding the width of c:
|
|
||||||
t.set_rotation(0)
|
|
||||||
t.set_va("center")
|
|
||||||
bbox1 = t.get_window_extent(renderer=renderer)
|
|
||||||
w = bbox1.width
|
|
||||||
h = bbox1.height
|
|
||||||
|
|
||||||
# ignore all letters that don't fit:
|
|
||||||
if rel_pos + w / 2 > l_fig[-1]:
|
|
||||||
t.set_alpha(0.0)
|
|
||||||
rel_pos += w
|
|
||||||
continue
|
|
||||||
|
|
||||||
elif c != " ":
|
|
||||||
t.set_alpha(1.0)
|
|
||||||
|
|
||||||
# finding the two data points between which the horizontal
|
|
||||||
# center point of the character will be situated
|
|
||||||
# left and right indices:
|
|
||||||
il = np.where(rel_pos + w / 2 >= l_fig)[0][-1]
|
|
||||||
ir = np.where(rel_pos + w / 2 <= l_fig)[0][0]
|
|
||||||
|
|
||||||
# if we exactly hit a data point:
|
|
||||||
if ir == il:
|
|
||||||
ir += 1
|
|
||||||
|
|
||||||
# how much of the letter width was needed to find il:
|
|
||||||
used = l_fig[il] - rel_pos
|
|
||||||
rel_pos = l_fig[il]
|
|
||||||
|
|
||||||
# relative distance between il and ir where the center
|
|
||||||
# of the character will be
|
|
||||||
fraction = (w / 2 - used) / r_fig_dist[il]
|
|
||||||
|
|
||||||
##setting the character position in data coordinates:
|
|
||||||
##interpolate between the two points:
|
|
||||||
x = self.__x[il] + fraction * (self.__x[ir] - self.__x[il])
|
|
||||||
y = self.__y[il] + fraction * (self.__y[ir] - self.__y[il])
|
|
||||||
|
|
||||||
# getting the offset when setting correct vertical alignment
|
|
||||||
# in data coordinates
|
|
||||||
t.set_va(self.get_va())
|
|
||||||
bbox2 = t.get_window_extent(renderer=renderer)
|
|
||||||
|
|
||||||
bbox1d = self.axes.transData.inverted().transform(bbox1)
|
|
||||||
bbox2d = self.axes.transData.inverted().transform(bbox2)
|
|
||||||
dr = np.array(bbox2d[0] - bbox1d[0])
|
|
||||||
|
|
||||||
# the rotation/stretch matrix
|
|
||||||
rad = rads[il]
|
|
||||||
rot_mat = np.array(
|
|
||||||
[
|
|
||||||
[math.cos(rad), math.sin(rad) * aspect],
|
|
||||||
[-math.sin(rad) / aspect, math.cos(rad)],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
##computing the offset vector of the rotated character
|
|
||||||
drp = np.dot(dr, rot_mat)
|
|
||||||
|
|
||||||
# setting final position and rotation:
|
|
||||||
t.set_position(np.array([x, y]) + drp)
|
|
||||||
t.set_rotation(degs[il])
|
|
||||||
|
|
||||||
t.set_va("center")
|
|
||||||
t.set_ha("center")
|
|
||||||
|
|
||||||
# updating rel_pos to right edge of character
|
|
||||||
rel_pos += w - used
|
|
|
@ -1,25 +1,19 @@
|
||||||
'''
|
'''
|
||||||
MIT License
|
Prettymaps - A minimal Python library to draw pretty maps from OpenStreetMap Data
|
||||||
|
Copyright (C) 2021 Marcelo Prates
|
||||||
|
|
||||||
Copyright (c) 2021 Marcelo de Oliveira Rosa Prates
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
This program is distributed in the hope that it will be useful,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
in the Software without restriction, including without limitation the rights
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
GNU Affero General Public License for more details.
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
You should have received a copy of the GNU Affero General Public License
|
||||||
copies or substantial portions of the Software.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
'''
|
'''
|
||||||
MIT License
|
Prettymaps - A minimal Python library to draw pretty maps from OpenStreetMap Data
|
||||||
|
Copyright (C) 2021 Marcelo Prates
|
||||||
|
|
||||||
Copyright (c) 2021 Marcelo de Oliveira Rosa Prates
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
This program is distributed in the hope that it will be useful,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
in the Software without restriction, including without limitation the rights
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
GNU Affero General Public License for more details.
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
You should have received a copy of the GNU Affero General Public License
|
||||||
copies or substantial portions of the Software.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ast import Dict
|
from ast import Dict
|
||||||
|
|
Ładowanie…
Reference in New Issue