Bài 13: Tạo các hàm để tải các lớp GeoPackage

Hiện tại chúng ta đã từng sử dụng GeoPackages. Ví dụ: trong Tải một lớp vectơ, chúng tôi đã giới thiệu cách tải một lớp cụ thể từ GeoPackage. Tuy nhiên, rất dễ mắc lỗi khi chỉ định tên lớp. Ví dụ:

iface.addVectorLayer('E:/Geodata/NaturalEarth/natural_earth_vector.gpkg|layername=foo', '', 'ogr') 

Gây ra lỗi vì không có lớp nào được gọi là foo trong GeoPackage: Lớp Layer không hợp lệ: “Layer is not valid: The layer E:/Geodata/NaturalEarth/natural_earth_vector.gpkg|layername=foo is not a valid layer and can not be added to the map.”

Tuy nhiên, lỗi này không rõ ràng lắm vì nó không cho chúng ta biết lý do tại sao lớp không hợp lệ. Sẽ thuận tiện hơn nhiều khi có một cách để thêm một lớp GeoPackage, lần đầu tiên kiểm tra xem lớp đó có thực sự tồn tại không. Vậy làm thế nào chúng ta có thể tìm ra các lớp có sẵn trong GeoPackage? – OGR ! Sử dụng OGR, chúng ta có thể mở GeoPackage và nhận danh sách các lớp của nó:

from osgeo import ogr
my_gpkg = 'E:/Geodata/NaturalEarth/natural_earth_vector.gpkg'
gpkg_layers = [l.GetName() for l in ogr.Open(my_gpkg )]
print(gpkg_layers) 

Vì vậy, đây là cách chúng ta có thể nhận được danh sách tất cả các lớp trong GeoPackage.

Tiếp theo, chúng ta có thể sử dụng danh sách này để kiểm tra một lớp nhất định có sẵn, ví dụ:

print('foo' in gpkg_layers) 

In ra False trên console.

Ngược lại:

print('ne_110m_land' in gpkg_layers) 

In ra True trên console.

Do đó, chúng ta có thể sử dụng câu lệnh này để quyết định xem có nên tải lớp hay hiển thị thông báo lỗi chính xác hơn không:

my_layer = 'foo'
if my_layer in layers:
iface.addVectorLayer(gpkg + "|layername=" + my_layer, my_layer, 'ogr')
else: 
print('Error: there is no layer named "{}" in {}!'.format(my_layer, gpkg)) 

Tất nhiên, thật tuyệt khi có thể sử dụng lại mã này cho các tên lớp khác nhau. Chúng ta có thể đạt được mục tiêu này bằng cách viết một chức năng mới. Hãy gọi hàm mới add_gpkg_layer:

def add_gpkg_layer(gpkg, layer):
layers = [l.GetName() for l in ogr.Open(gpkg)]
if layer in layers:
iface.addVectorLayer(gpkg + "|layername=" + layer, layer, 'ogr')
else: 
print('Error: there is no layer named "{}" in {}!'.format(layer, gpkg)) 

Dòng đầu tiên của định nghĩa hàm của chúng ta bắt đầu bằng def theo sau là tên hàm và các tham số hàm trong ngoặc đơn và dấu chấm phẩy ở cuối. Mã code chức năng theo sau dấu chấm phẩy phải được thụt lề.

Bây giờ chúng ta có thể thêm các lớp mới một cách dễ dàng:

add_gpkg_layer(my_gpkg, 'foo') 
add_gpkg_layer(my_gpkg, 'ne_110m_land') 

Tất nhiên, chúng ta cũng có thể tạo một hàm tải nhiều lớp:

def add_layers_from_gpkg(gpkg, layers):
for layer in layers:
add_gpkg_layer(gpkg, layer) 

Lưu ý cách hàm này sử dụng lại hàm add_gpkg_layer được xác định trước đó.

Với chức năng này, giờ đây chúng ta có thể tải nhiều lớp một cách thuận tiện trong một lần:

add_layers_from_gpkg(my_gpkg, ['ne_110m_land', 'ne_110m_lakes']) 

Cuối cùng, nếu chúng ta muốn tải tất cả các lớp:

def add_all_layers_from_gpkg(gpkg):
layers = [l.GetName() for l in ogr.Open(gpkg)]
add_layers_from_gpkg(gpkg, layers) 

Hãy cẩn thận khi sử dụng chức năng này với GeoPackages lớn vì có thể mất một lúc để tải tất cả các lớp !

Trên đây là những điều cơ bản để viết các hàm mới trong Python. Các hàm làm cho nó có thể sử dụng lại mã của bạn mà không phải sao chép-dán lại nhiều lần. Bạn cũng đã thấy cách sử dụng ORG. Mở để tạo danh sách tất cả các lớp có sẵn trong GeoPackage.

Bình luận bằng Facebook Comments