Tạo shapefile lưới đa giác vuông với Python?


9

Tôi có tọa độ sau

minx, maxx, miny ,maxy = 448262.080078, 450360.750122, 6262492.020081, 6262938.950073

Tôi muốn tạo một lưới vuông có kích thước 1 m bằng python.

import math


minx,maxx,miny,maxy = 448262.080078, 450360.750122, 6262492.020081, 6262938.950073
size = 1

def set_bbox(minx, maxx, miny, maxy, distx, disty):
    nx = int(math.ceil(abs(maxx - minx)/distx))
    ny = int(math.ceil(abs(maxy - miny)/disty))
    new_maxx = minx + (nx*distx)
    new_miny = maxy - (ny*disty)
    return ((minx, new_maxx, new_miny, maxy),ny,nx)

# shift the bottom (right - down)
coord, ny, nx = set_bbox(minx,maxx,miny,maxy,size,size)
# left-up origin
origin = coord[0],coord[3]
# number of tiles
ncell = ny*nx

Điều này có được gắn với bất kỳ nền tảng GIS cụ thể nào không hoặc là yêu cầu để thực hiện điều này trong python thuần mà không có bất kỳ định dạng đầu ra cụ thể nào (ví dụ: shapefile, textfile, v.v.)

Cảm ơn @Dan, tôi muốn thực hiện trong python thuần và đầu ra sẽ ở định dạng shapefile
Gianni

Cấp giấy phép ArcInfo của ArcMap có công cụ Fishnet nhưng bạn chưa cho biết bạn dự định tạo shapefile như thế nào.

Xin lỗi tôi không sử dụng Phần mềm thương mại. Tôi thích chương trình bằng ngôn ngữ thuần Java, Python, C ++.
Gianni

1
Nhưng bạn không phiền khi sử dụng một thư viện như GDAL / OGR ( pypi.python.org/pypi/GDAL ) hoặc pyshp ( pypi.python.org/pypi/pyshp )?
Snorfalorpagus

Câu trả lời:


11

Kịch bản sau đây sẽ thực hiện công việc với GDAL và Python:

import os, sys
import ogr
from math import ceil

def main(outputGridfn,xmin,xmax,ymin,ymax,gridHeight,gridWidth):

    # convert sys.argv to float
    xmin = float(xmin)
    xmax = float(xmax)
    ymin = float(ymin)
    ymax = float(ymax)
    gridWidth = float(gridWidth)
    gridHeight = float(gridHeight)

    # get rows
    rows = ceil((ymax-ymin)/gridHeight)
    # get columns
    cols = ceil((xmax-xmin)/gridWidth)

    # start grid cell envelope
    ringXleftOrigin = xmin
    ringXrightOrigin = xmin + gridWidth
    ringYtopOrigin = ymax
    ringYbottomOrigin = ymax-gridHeight

    # create output file
    outDriver = ogr.GetDriverByName('ESRI Shapefile')
    if os.path.exists(outputGridfn):
        os.remove(outputGridfn)
    outDataSource = outDriver.CreateDataSource(outputGridfn)
    outLayer = outDataSource.CreateLayer(outputGridfn,geom_type=ogr.wkbPolygon )
    featureDefn = outLayer.GetLayerDefn()

    # create grid cells
    countcols = 0
    while countcols < cols:
        countcols += 1

        # reset envelope for rows
        ringYtop = ringYtopOrigin
        ringYbottom =ringYbottomOrigin
        countrows = 0

        while countrows < rows:
            countrows += 1
            ring = ogr.Geometry(ogr.wkbLinearRing)
            ring.AddPoint(ringXleftOrigin, ringYtop)
            ring.AddPoint(ringXrightOrigin, ringYtop)
            ring.AddPoint(ringXrightOrigin, ringYbottom)
            ring.AddPoint(ringXleftOrigin, ringYbottom)
            ring.AddPoint(ringXleftOrigin, ringYtop)
            poly = ogr.Geometry(ogr.wkbPolygon)
            poly.AddGeometry(ring)

            # add new geom to layer
            outFeature = ogr.Feature(featureDefn)
            outFeature.SetGeometry(poly)
            outLayer.CreateFeature(outFeature)
            outFeature.Destroy

            # new envelope for next poly
            ringYtop = ringYtop - gridHeight
            ringYbottom = ringYbottom - gridHeight

        # new envelope for next poly
        ringXleftOrigin = ringXleftOrigin + gridWidth
        ringXrightOrigin = ringXrightOrigin + gridWidth

    # Close DataSources
    outDataSource.Destroy()


if __name__ == "__main__":

    #
    # example run : $ python grid.py <full-path><output-shapefile-name>.shp xmin xmax ymin ymax gridHeight gridWidth
    #

    if len( sys.argv ) != 8:
        print "[ ERROR ] you must supply seven arguments: output-shapefile-name.shp xmin xmax ymin ymax gridHeight gridWidth"
        sys.exit( 1 )

    main( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7] )

6

Tập lệnh Python này sử dụng thư viện pyshp , theo đề xuất của user16044:

import shapefile as shp
import math

minx,maxx,miny,maxy = 448262.080078, 450360.750122, 6262492.020081, 6262938.950073
dx = 100
dy = 100

nx = int(math.ceil(abs(maxx - minx)/dx))
ny = int(math.ceil(abs(maxy - miny)/dy))

w = shp.Writer(shp.POLYGON)
w.autoBalance = 1
w.field("ID")
id=0

for i in range(ny):
    for j in range(nx):
        id+=1
        vertices = []
        parts = []
        vertices.append([min(minx+dx*j,maxx),max(maxy-dy*i,miny)])
        vertices.append([min(minx+dx*(j+1),maxx),max(maxy-dy*i,miny)])
        vertices.append([min(minx+dx*(j+1),maxx),max(maxy-dy*(i+1),miny)])
        vertices.append([min(minx+dx*j,maxx),max(maxy-dy*(i+1),miny)])
        parts.append(vertices)
        w.poly(parts)
        w.record(id)

w.save('polygon_grid')

Lưu ý: một ô vuông có kích thước 1 m với mức độ tương đương với một lớp chứa khoảng 1 triệu đa giác và do đó hiệu suất của tập lệnh giảm một cách hợp lý.


1

Câu hỏi này đã được trả lời từ thời gian trước, nhưng tôi thêm một giải pháp khác bằng thư viện shapely và fiona:

import fiona
from shapely.geometry import mapping, LineString, MultiLineString

file = 'input.shp'
with fiona.open(file, 'r') as ds_in:
    num_tiles = 5
    schema = {
    "geometry": "MultiLineString",
    "properties": {"id": "int"}
     }
minx, miny, maxx, maxy = ds_in.bounds
dx = (maxx - minx) / num_tiles
dy = (maxy - miny) / num_tiles

lines = []
for x in range(num_tiles + 1):
    lines.append(LineString([(minx + x * dx, miny), (minx + x * dx, maxy)]))
for y in range(num_tiles + 1):
    lines.append(LineString([(minx, miny + y * dy), (maxx, miny + y * dy)]))
grid = MultiLineString(lines)
out = 'gridtest.shp'
with fiona.open(out, 'w', driver=ds_in.driver, schema=schema, crs=ds_in.crs) as ds_dst:
    ds_dst.write({'geometry': mapping(grid), "properties": {"id": 0}})

-1

Câu trả lời cho việc tạo Shapefile lưới fishnet trong QGIS? hiển thị tùy chọn tạo lưới trong hộp công cụ xử lý QGIS.


OP tuyên bố rằng anh ấy / cô ấy thích một ví dụ trong Python thuần túy hơn là với một phần mềm
CườiU

Đưa ra các câu trả lời khác cho các thư viện nhập, nhập các mô-đun QGIS là một cách hợp lệ để chuyển tiếp GUI. Giống như trong câu trả lời này gis.stackexchange.com/questions/79916/ từ
user965586

Các câu trả lời khác cung cấp mã vì vậy nếu bạn cũng vậy thì tôi nghĩ nó sẽ được nhận tốt hơn.
PolyGeo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.