5

我有一个 ESRI shapefile(来自这里: http: //pubs.usgs.gov/ds/425/)。我希望使用 python 从给定纬度/经度的形状文件(在这种情况下为表面材料)中查找信息。

解决这个问题的最佳方法是什么?

谢谢。

最终解决方案:

#!/usr/bin/python

from osgeo import ogr, osr

dataset = ogr.Open('./USGS_DS_425_SHAPES/Surficial_materials.shp')
layer = dataset.GetLayerByIndex(0)
layer.ResetReading()

# Location for New Orleans: 29.98 N, -90.25 E
point = ogr.CreateGeometryFromWkt("POINT(-90.25 29.98)")

# Transform the point into the specified coordinate system from WGS84
spatialRef = osr.SpatialReference()
spatialRef.ImportFromEPSG(4326)
coordTransform = osr.CoordinateTransformation(
        spatialRef, layer.GetSpatialRef())

point.Transform(coordTransform)

for feature in layer:
    if feature.GetGeometryRef().Contains(point):
        break

for i in range(feature.GetFieldCount()):
    print feature.GetField(i)
4

3 回答 3

3

查看Python Shapefile 库

这应该给你几何和不同的信息。

于 2011-01-04T19:08:05.817 回答
2

您可以使用 python 绑定到gdal/ogr工具包。这是一个例子:

from osgeo import ogr

ds = ogr.Open("somelayer.shp")
lyr = ds.GetLayerByName("somelayer")
lyr.ResetReading()

point = ogr.CreateGeometryFromWkt("POINT(4 5)")

for feat in lyr:
    geom = feat.GetGeometryRef()
    if geom.Contains(point):
        sm = feat.GetField(feat.GetFieldIndex("surface_material"))
        # do stuff...
于 2011-01-04T20:08:18.710 回答
2

另一种选择是使用 Shapely(基于 GEOS 的 Python 库,PostGIS 的引擎)和 Fiona(基本上用于读取/写入文件):

import fiona
import shapely

with fiona.open("path/to/shapefile.shp") as fiona_collection:

    # In this case, we'll assume the shapefile only has one record/layer (e.g., the shapefile
    # is just for the borders of a single country, etc.).
    shapefile_record = fiona_collection.next()

    # Use Shapely to create the polygon
    shape = shapely.geometry.asShape( shapefile_record['geometry'] )

    point = shapely.geometry.Point(32.398516, -39.754028) # longitude, latitude

    # Alternative: if point.within(shape)
    if shape.contains(point):
        print "Found shape for point."

请注意,如果多边形很大/很复杂(例如,某些海岸线极不规则的国家/地区的 shapefile),则进行多边形中的点测试可能会很昂贵。在某些情况下,在进行更密集的测试之前,它可以帮助使用边界框快速排除事物:

minx, miny, maxx, maxy = shape.bounds
bounding_box = shapely.geometry.box(minx, miny, maxx, maxy)

if bounding_box.contains(point):
    ...

最后,请记住,加载和解析大型/不规则形状文件需要一些时间(不幸的是,这些类型的多边形在内存中通常也很昂贵)。

于 2013-09-11T19:13:39.673 回答