Поскольку, похоже, вам действительно нужно решение, я дам вам один способ сделать это.
ПРИМЕЧАНИЕ : я не призываю вас манипулировать файлом .svg
вручную.Однако, если выбора нет, давайте сделаем это!
Решение предполагает , что процесс, не являющийся питоном, не изменяет файл в форме.
Чтобы преодолетьСоздав файл .svg
(по крайней мере, для меня черный ящик), вы можете просто создать другое изображение с графиком ожидаемых координат, сохранить изображение как временный файл .svg
, найти точки координат (в файле .svg
) и, наконец,добавьте их в исходный файл карты.
Я определяю 3 метода: - createMap
, чтобы нарисовать карту и сохранить вывод как .png
файл - get_svg_coordinates
: создать временную карту (.svg
файл), прочитать координаты точки, удалить временный файл, вернуть координаты точки.- add_circle
: нарисовать кружок на существующем .svg
файле карты.
Здесь код: (рабочий пример)
# Import modules
import os
import re
# os.environ['PROJ_LIB'] = r'C:\Users\...\Library\share'
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
def createMap(lats, lons, color='r', figure_name="basemap.svg", show=False):
""" Create a map from points coordinates + export to .csv file
Arguments
:param lats: latitudes
:param lons: longitudes
:param color='r': color points
:param figure_name="basemap.svg": name output file
:param show=False: show the map
"""
# Same code as yours
plt.figure(figsize=(15, 15/2))
m = Basemap(projection='robin', lon_0=0, resolution='c')
m.drawcountries(color='#ffffff', linewidth=0.75)
m.fillcontinents(color='#c0c0c0', lake_color='#e6f5ff')
m.drawmapboundary(fill_color='#e6f5ff', linewidth=1, color='#000000') # Ocean
x, y = m(lons, lats)
plt.plot(x, y, 'bo', color=color, markersize=5)
plt.savefig(figure_name, figsize=(24, 12))
if show: plt.show()
def get_svg_coordinates(lat, lon, color='#ff0000', figure_temp_name="tmp_figure.svg"):
""" Create a temporary file using the createMap function
Find the point coordinates inside (using regex check)
Remove temporary csv file
Arguments
:param lat: new point latitude
:param lon: new point longitude
:param color='#ff0000': point color
:param figure_temp_name="tmp_figure.svg": temp file name
"""
createMap(lat, lon, color=color, figure_name=figure_temp_name)
with open(figure_temp_name, "r") as f:
# read file
content = f.read()
# Find x - y values (pattern ' x=' is unique is you are using 1 point)
x = re.findall(r'<use.*x=\"(\d*\.*\d*)\"', content)
y = re.findall(r'<use.*y=\"(\d*\.*\d*)\"', content)
# remove file
os.remove(figure_temp_name)
return x, y
def add_circle(map_file_name, x, y):
""" Draw circle at the end of file
Arguments:
:param map_file_name: filename (adding circle)
:param x: x coordinates (results of get_svg_coordinates method)
:param y: y coordinates (results of get_svg_coordinates method)
"""
with open(map_file_name, "r+") as f:
content = f.readlines()
# get number of lines in file
for i, l in enumerate(content):
pass
# Add content
content.insert(i, '<circle fill="blue" cx="{0}" cy="{1}" r="2"/>'.format(x[0], y[0]))
f.seek(0) # file pointer locates at the beginning to write the whole file again
f.writelines(content) # rewrite file
# Berlin & New York & Sydney
lats = [52.516667] # [52.516667, 40.730610]
lons = [13.388889] # [13.388889, -73.935242]
# create your initial svg map
map_file_name = "basemap.svg"
createMap(lats, lons, figure_name=map_file_name)
# Find new position point on svg file
# Define coordinates points
NewYork_lat = 40.730610
NewYork_long = -73.935242
x, y = get_svg_coordinates(NewYork_lat, NewYork_long)
add_circle(map_file_name, x, y)
Примечание:
Я не знаком с файлом .svg
.Чтобы ответить на вопрос, я добавляю <circle fill="blue" cx="???" cy="???" r="2"/>
в конце файла, как и ожидалось.Однако, может быть, лучше определить весь DOM <g id="line2d_1">
и скопировать его.
Фрагмент работает для одного изображения, я позволю вам обобщить для набора точек.