我必须编写下面的代码,它读取(地理)坐标(经度,纬度)的文件,从这些点中的距离矩阵计算最小生成树,并使用Matplotlib绘制生成的树。
import warnings
import numpy as np
from scipy.spatial.distance import pdist, squareform
import matplotlib.pyplot as plt
import simplekml
warnings.filterwarnings("ignore")
def minimum_spanning_tree(X, copy_X=True):
"""X are edge weights of fully connected graph"""
if copy_X:
X = X.copy()
if X.shape[0] != X.shape[1]:
raise ValueError("X needs to be square matrix of edge weights")
n_vertices = X.shape[0]
spanning_edges = []
# initialize with node 0:
visited_vertices = [0]
num_visited = 1
# exclude self connections:
diag_indices = np.arange(n_vertices)
X[diag_indices, diag_indices] = np.inf
while num_visited != n_vertices:
new_edge = np.argmin(X[visited_vertices], axis=None)
# 2d encoding of new_edge from flat, get correct indices
new_edge = divmod(new_edge, n_vertices)
new_edge = [visited_vertices[new_edge[0]], new_edge[1]]
# add edge to tree
spanning_edges.append(new_edge)
visited_vertices.append(new_edge[1])
# remove all edges inside current tree
X[visited_vertices, new_edge[1]] = np.inf
X[new_edge[1], visited_vertices] = np.inf
num_visited += 1
return np.vstack(spanning_edges)
def test_mst():
P = np.loadtxt("testdata.csv", delimiter=',', skiprows=1)
X = squareform(pdist(P))
edge_list = minimum_spanning_tree(X)
plt.scatter(P[:, 0], P[:, 1], c='b')
edges = []
for edge in edge_list:
i, j = edge
plt.plot([P[i, 0], P[j, 0]], [P[i, 1], P[j, 1]], c='b')
edges.append([(P[i, 0], P[j, 0]), (P[i, 1], P[j, 1])])
plt.show()
# Save KML file
kml = simplekml.Kml()
for i in range(len(edges)):
line = kml.newlinestring(name="Track" + str(i + 1), coords=edges[i])
line.style.linestyle.width = 3
line.style.linestyle.color = simplekml.Color.red
kml.save("mst.kml")
if __name__ == "__main__":
test_mst()
这是我的测试数据:
Longitude,Latitude
-61.05,10.4
-79.4333333333,9.15
-70.6666666667,9.5333333333
-63.1166666667,7.9166666667
-63.1166666667,10.55
-81.1833333333,7.5166666667
-56.4833333333,3.1
-60.5,3.9333333333
-81.0166666667,7.6666666667
-67.4333333333,8.9333333333
-65.9666666667,10.3166666667
-78.9333333333,8.3833333333
-72.8666666667,9.8333333333
-68.4,10.6166666667
-72.9833333333,10.6166666667
它工作正常并显示下图:
但是,我还想将结果树的坐标保存为KML格式,以便使用Google Earth绘制它。然后我存储传递的相同坐标以将绘图构建到元组列表中,然后将其传递给simpleKml对象。它不起作用,Google地球没有正确显示树。
因此,一般而言,我的问题是:我如何保存(以任何格式)绘图的坐标,以便能够完全按照Matplotlib显示的方式重建它?
提前感谢您提供的任何帮助。
编辑:以下是Google地球中显示的KML文件:
以下是应该出现的方式(此图是使用Matplotlib和Basemap创建的):
答案 0 :(得分:1)
唯一的另一种选择是转换为.csv然后转换为xml
https://developers.google.com/kml/articles/csvtokml
不确定这是否是您正在寻找的
答案 1 :(得分:1)
查看the simplekml documentation,坐标需要以(lon,lat)
对的形式给出。
所以而不是
# edges.append([(P[i, 0], P[j, 0]), (P[i, 1], P[j, 1])])
你需要
edges.append([(P[i, 0], P[i, 1]), (P[j, 0],P[j, 1] )])
google earth的屏幕截图: