From 9c77f58f305330534782cb47d4906123c415db0d Mon Sep 17 00:00:00 2001 From: John Truckenbrodt Date: Thu, 27 Jun 2024 11:50:40 +0200 Subject: [PATCH 1/5] [Vector.addfield] new argument 'values' --- spatialist/vector.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spatialist/vector.py b/spatialist/vector.py index e3f37ae..111f0b7 100644 --- a/spatialist/vector.py +++ b/spatialist/vector.py @@ -168,7 +168,7 @@ def addfeature(self, geometry, fields=None): feature = None self.init_features() - def addfield(self, name, type, width=10): + def addfield(self, name, type, width=10, values=None): """ add a field to the vector layer @@ -178,9 +178,12 @@ def addfield(self, name, type, width=10): the field name type: int the OGR Field Type (OFT), e.g. ogr.OFTString. - See `Module ogr `_. + See :class:`osgeo.ogr.FieldDefn`. width: int the width of the new field (only for ogr.OFTString fields) + values: list + an optional list with values for each feature to assign to the new field. + The length must be identical to the number of features. Returns ------- @@ -190,6 +193,12 @@ def addfield(self, name, type, width=10): if type == ogr.OFTString: fieldDefn.SetWidth(width) self.layer.CreateField(fieldDefn) + if values is not None: + if len(values) != self.nfeatures: + raise RuntimeError('number of values does not match number of features') + for i, feature in enumerate(self.layer): + feature.SetField(name, values[i]) + self.layer.SetFeature(feature) def addlayer(self, name, srs, geomType): """ From 3dbccd74629c960e37cf03b5abcdfe8edd90956e Mon Sep 17 00:00:00 2001 From: John Truckenbrodt Date: Sun, 30 Jun 2024 09:10:11 +0200 Subject: [PATCH 2/5] [Vector.addfield] support setting all types (also lists) --- spatialist/vector.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spatialist/vector.py b/spatialist/vector.py index 111f0b7..d6b69b6 100644 --- a/spatialist/vector.py +++ b/spatialist/vector.py @@ -189,15 +189,18 @@ def addfield(self, name, type, width=10, values=None): ------- """ - fieldDefn = ogr.FieldDefn(name, type) + type_name = ogr.GetFieldTypeName(type) + field_defn = ogr.FieldDefn(name, type) if type == ogr.OFTString: - fieldDefn.SetWidth(width) - self.layer.CreateField(fieldDefn) + field_defn.SetWidth(width) + self.layer.CreateField(field_defn) if values is not None: if len(values) != self.nfeatures: raise RuntimeError('number of values does not match number of features') for i, feature in enumerate(self.layer): - feature.SetField(name, values[i]) + index = feature.GetFieldIndex(name) + method = getattr(feature, f'SetField{type_name}') + method(index, values[i]) self.layer.SetFeature(feature) def addlayer(self, name, srs, geomType): From 662dec7c34dd4ebffc6dd0f06f2c3f421eb5ae2d Mon Sep 17 00:00:00 2001 From: John Truckenbrodt Date: Wed, 17 Jul 2024 18:00:36 +0200 Subject: [PATCH 3/5] [Vector.addfield] improvements in selecting field setter method --- spatialist/vector.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/spatialist/vector.py b/spatialist/vector.py index d6b69b6..1ae4221 100644 --- a/spatialist/vector.py +++ b/spatialist/vector.py @@ -194,12 +194,21 @@ def addfield(self, name, type, width=10, values=None): if type == ogr.OFTString: field_defn.SetWidth(width) self.layer.CreateField(field_defn) + if type_name in ['String', 'Integer', 'Real', 'Binary']: + method_name = 'SetField' + elif type_name in ['StringList', 'DoubleList', 'IntegerList', + 'Integer64', 'Integer64List']: + method_name = f'SetField{type_name}' + elif type_name == 'RealList': + method_name = 'SetFieldDoubleList' + else: + raise ValueError(f'Unsupported field type: {type_name}') if values is not None: if len(values) != self.nfeatures: raise RuntimeError('number of values does not match number of features') for i, feature in enumerate(self.layer): index = feature.GetFieldIndex(name) - method = getattr(feature, f'SetField{type_name}') + method = getattr(feature, method_name) method(index, values[i]) self.layer.SetFeature(feature) From 7420304297b2dd0f96d64d1149ab97e913158385 Mon Sep 17 00:00:00 2001 From: John Truckenbrodt Date: Wed, 17 Jul 2024 18:01:09 +0200 Subject: [PATCH 4/5] [test_spatial] restructured import statements --- spatialist/tests/test_spatial.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spatialist/tests/test_spatial.py b/spatialist/tests/test_spatial.py index 8d75c4d..4515c34 100644 --- a/spatialist/tests/test_spatial.py +++ b/spatialist/tests/test_spatial.py @@ -4,13 +4,13 @@ import platform import numpy as np from osgeo import ogr, gdal -from spatialist import crsConvert, haversine, Raster, stack, ogr2ogr, gdal_translate, gdal_rasterize, bbox, rasterize, \ - gdalwarp, utm_autodetect, coordinate_reproject, cmap_mpl2gdal -from spatialist.raster import Dtype, png -from spatialist.vector import feature2vector, dissolve, Vector, intersect +from spatialist.raster import Dtype, png, Raster, stack, rasterize +from spatialist.vector import feature2vector, dissolve, Vector, intersect, bbox from spatialist.envi import hdr, HDRobject from spatialist.sqlite_util import sqlite_setup, __Handler from spatialist.ancillary import parallel_apply_along_axis +from spatialist.auxil import (crsConvert, haversine, ogr2ogr, gdal_translate, gdal_rasterize, gdalwarp, + utm_autodetect, coordinate_reproject, cmap_mpl2gdal) import logging From 18a8baf0bebec59b70b51fb14afd0f50f18e95a9 Mon Sep 17 00:00:00 2001 From: John Truckenbrodt Date: Wed, 17 Jul 2024 18:01:58 +0200 Subject: [PATCH 5/5] [test_spatial.test_addfield] new method --- spatialist/tests/test_spatial.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spatialist/tests/test_spatial.py b/spatialist/tests/test_spatial.py index 4515c34..ea71abf 100644 --- a/spatialist/tests/test_spatial.py +++ b/spatialist/tests/test_spatial.py @@ -426,3 +426,17 @@ def test_png(tmpdir, testdata): outname = os.path.join(str(tmpdir), 'test_rgb.png') with Raster(src) as ras: png(src=ras, dst=outname, percent=100, scale=(2, 98), worldfile=True) + + +def test_addfield(): + extent = {'xmin': 10, 'xmax': 11, 'ymin': 50, 'ymax': 51} + with bbox(coordinates=extent, crs=4326) as box: + box.addfield(name='test1', type=ogr.OFTString, values=['a']) + box.addfield(name='test2', type=ogr.OFTStringList, values=[['a', 'b']]) + box.addfield(name='test3', type=ogr.OFTInteger, values=[1]) + box.addfield(name='test4', type=ogr.OFTIntegerList, values=[[1, 2]]) + box.addfield(name='test5', type=ogr.OFTInteger64, values=[1]) + box.addfield(name='test6', type=ogr.OFTInteger64List, values=[[1, 2]]) + box.addfield(name='test7', type=ogr.OFTReal, values=[1]) + box.addfield(name='test8', type=ogr.OFTRealList, values=[[1., 2.]]) + box.addfield(name='test9', type=ogr.OFTBinary, values=[b'1'])