【问题标题】:Creating a shapefile of straight segments with pyshp?用pyshp创建一个直线段的shapefile?
【发布时间】:2017-08-22 14:33:50
【问题描述】:

使用 Python 和 pyshp 库,我正在尝试从以下数据(存储在列表中)创建一个 shapefile:

edge_list = [
    [-40.5, -20.666],
    [-39.849998, -18.700001],
    [-39.816002, -19.6],
    [-40.071999, -19.391001],
    [-40.150002, -19.933001],
    [-39.733002, -18.533001],
    [-39.833, -18.733],
    [-39.708, -18.419001],
    [-39.370998, -17.891001],
    [-39.200001, -17.417],
    [-39.216999, -17.299999],
    [-39.167, -17.083],
    [-39.049999, -16.433001],
    [-38.932999, -13.967],
    [-39.083, -16.583],
    [-39.0, -13.916],
    [-38.900002, -13.6],
]

这是我的一段代码(其中 edge_list 是上面的列表):

w = shapefile.Writer()
w.line(parts=[edge_list])
w.field("COMMON_ID", 'C')
w.save("test")

我明白了:

但我想得到这个:

有什么提示吗?

编辑:这是完整的测试代码,但内容不多。文件“temp.csv”只包含上面显示的两列点,用逗号分隔,并带有一个额外的标题行(x,y)。

import csv
import shapefile

data = csv.reader(open("test.csv", "rb"), delimiter = ',')
data.next() # skip header line
edge_list = []
for row in data:
    edge_list.append([float(row[0]), float(row[1])])

for e in range(len(edge_list)):
    print "x=", edge_list[e][0], "y=", edge_list[e][1]

w = shapefile.Writer()
w.line(parts=[edge_list])
w.field("COMMON_ID", 'C')
w.save("test")

【问题讨论】:

  • 您需要edit 您的问题,并准确显示edge_listw.line(parts=[edge_list]) 调用中作为参数传递时的值。现在您的问题中显示的不是有效的 Python 数据。
  • 我的问题中显示的数据是 edge_list 变量内容的精确打印:for e in range(len(edge_list): print edge_list[e].
  • 好的,这样更好,但仍然不完全正确——我会修复它。
  • @martineau 显然,事情没那么简单。请参阅 OP 对我的回答的评论。在某处有numpy.float32s。
  • @Scott,对,我就是这么做的。

标签: python shapefile pyshp


【解决方案1】:

免责声明:我没有使用过 shapefile 或 pyshp。但我知道画线的方法。

我看到的是它按照您输入点的顺序绘制线条。它连接点,这就是你的点的顺序。你需要做的是重新排序edge_list中的点。

在你的情况下,如果你的 y 变量是有序的,你的点会很好看。

所以,尝试替换这一行:

w.line(parts=[edge_list])

用这个:

w.line(parts=sorted(edge_list, key=lambda point: point[1]))

这将按 y 变量对您的点进行排序,并且应该按照您想要的方式绘制线条。

【讨论】:

  • 您可能需要w.line(parts=list(sorted(edge_list, key=lambda point: point[1]))),因为您的示例有parts=[edge_list]。我不认为[ ] 是必要的,但是如果您需要额外级别的列表,那就是如何获得它。
  • 嗨!感谢您的快速回复。我完全同意您的建议,即我的问题的答案需要按 y 轴对点进行排序,但是它不起作用。尝试运行建议的代码时,出现错误:“TypeError: 'numpy.float32' object is not iterable”。
  • martineau 的想法是正确的——我们需要看看一些实际的代码。排序将解决您的问题。向我们展示您的代码中的内容将帮助我们告诉您如何对其进行排序。
  • 按照我的第一条评论,用它周围的list 试试。这类似于您最初发布的代码,其中您使用 edge_list,它应该已经是一个点列表,并在其周围放置 [ ]。我刚刚测试了sorted(edge_list, key=lambda pair: pair[1]), and it returns exactly what it should - a list of points, sorted on the y axis. So if you needed parts=[edge_list], you'll need parts=list(sorted(edge_list, key = lambda point: point[1])))`。
  • 我也尝试了列表功能,结果相同。但我只是在 将列表传递给 shapefile.lines 之前对其进行排序!它现在生成正确的行!非常感谢你和马蒂诺!
【解决方案2】:

我通过简单地对列表进行排序将其传递给 shapefile.line() 得到了解决方案。

这是完整的、完全可以工作的代码:

import csv
import shapefile

data = csv.reader(open("test.csv", "rb"), delimiter = ',')
data.next() # skip header line
edge_list = []
for row in data:
    edge_list.append([float(row[0]), float(row[1])])

## sort list before passing it to shapefile.line function
edge_list = list(sorted(edge_list, key=lambda point: point[1]))

for e in range(len(edge_list)):
    print "x=", edge_list[e][0], "y=", edge_list[e][1]

w = shapefile.Writer()
w.line(parts=[edge_list]) ## this now works OK!
w.field("COMMON_ID", 'C')
w.save("test")

【讨论】:

    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    相关资源
    最近更新 更多