Factory methods — quick object creation

Several WOLFHECE classes provide factory methods to create instances in a single call, without setting attributes one by one.

This notebook groups them for header_wolf, WolfArray, vector, zone and Zones. Each section is self-contained; see the dedicated tutorials for in-depth usage.

[1]:
import numpy as np
from pathlib import Path
import tempfile

tmpdir = Path(tempfile.mkdtemp())

1. header_wolf factories

Factory

Input

Key feature

make(orig, nb, d)

origin + cell count + resolution

Simplest one-liner

make_from_xybounds_grid(xbounds, ybounds, d)

spatial bounds + resolution

grid_to_align snaps origin

from_slices(x_slice, y_slice, d)

Python slices + resolution

Handy for sub-windows

from_dict(d)

dict

Deserialization / config files

[2]:
from wolfhece.wolf_array import header_wolf

# --- make: origin + cell count + resolution ---
h = header_wolf().make(
    orig=(220000.0, 130000.0),
    nb=(100, 80),
    d=(1.0, 1.0),
)
print(f"make          : {h.nbx}x{h.nby}, orig=({h.origx}, {h.origy}), d=({h.dx}, {h.dy})")

# --- make_from_xybounds_grid: from spatial bounds ---
h2 = header_wolf.make_from_xybounds_grid(
    xbounds=(220000.0, 220100.0),
    ybounds=(130000.0, 130080.0),
    d=(2.0, 2.0),
)
print(f"from_xybounds : {h2.nbx}x{h2.nby}, orig=({h2.origx}, {h2.origy}), d=({h2.dx}, {h2.dy})")

# --- with grid alignment (snaps origin to existing grid) ---
h3 = header_wolf.make_from_xybounds_grid(
    xbounds=(220003.7, 220100.0),
    ybounds=(130002.1, 130080.0),
    d=(1.0, 1.0),
    grid_to_align=h,
)
print(f"aligned       : orig=({h3.origx}, {h3.origy})  (snapped to h)")

# --- from_slices: index ranges ---
h4 = header_wolf.from_slices(
    x_slice=slice(10, 60),
    y_slice=slice(5, 45),
    d=(1.0, 1.0),
)
print(f"from_slices   : {h4.nbx}x{h4.nby}, orig=({h4.origx}, {h4.origy})")
make          : 100x80, orig=(220000.0, 130000.0), d=(1.0, 1.0)
from_xybounds : 50x40, orig=(220000.0, 130000.0), d=(2.0, 2.0)
aligned       : orig=(220003.0, 130002.0)  (snapped to h)
from_slices   : 50x40, orig=(10.0, 5.0)

2. WolfArray / WolfArrayModel factories

Creation path

Code

Notes

From header (empty)

WolfArray(srcheader=h)

Array filled with ones

From header + numpy

WolfArray(srcheader=h, np_source=arr)

Wraps existing array

From file

WolfArray(fname='dem.bin')

.bin, .tif, .npy, .vrt

Clone / crop

WolfArray(mold=other, crop=bbox)

Deep copy, optional crop

Merge multiple

WolfArrayModel.merge([a, b, c])

Union of several arrays

From XYZ file

WolfArrayModel.set_general_frame_from_xyz(f, dx, dy)

Text XYZ

Reproject CRS

WolfArrayModel.from_other_epsg_coo(f, …)

GDAL reprojection

[3]:
from wolfhece.wolf_array import WolfArray, header_wolf
from wolfhece.wolf_array._header_wolf import WOLF_ARRAY_FULL_SINGLE

# --- From header (empty array) ---
h = header_wolf().make(orig=(220000.0, 130000.0), nb=(100, 80), d=(1.0, 1.0))
wa = WolfArray(srcheader=h, whichtype=WOLF_ARRAY_FULL_SINGLE)
print(f"From header      : shape={wa.nbx}x{wa.nby}, dtype={wa.array.dtype}")

# --- From header + numpy array ---
data = np.random.rand(100, 80).astype(np.float32)
wa2 = WolfArray(srcheader=h, np_source=data, whichtype=WOLF_ARRAY_FULL_SINGLE)
print(f"From np_source   : min={wa2.array.min():.3f}, max={wa2.array.max():.3f}")

# --- Clone (deep copy) ---
wa3 = WolfArray(mold=wa2)
print(f"Clone            : same origin? {wa3.origx == wa2.origx}")

# --- Clone + crop ---
wa4 = WolfArray(mold=wa2, crop=[[220010.0, 220060.0], [130010.0, 130050.0]])
print(f"Cropped clone    : shape={wa4.nbx}x{wa4.nby}")
From header      : shape=100x80, dtype=float32
From np_source   : min=0.000, max=1.000
Clone            : same origin? True
Cropped clone    : shape=50x40
[5]:
from wolfhece.wolf_array import WolfArrayModel

# --- _new_like: empty array with same geometry ---
wa_empty = wa2._new_like()
print(f"_new_like  : shape={wa_empty.nbx}x{wa_empty.nby}, all zeros? {(wa_empty.array == 0)}")

# --- crop_array: extract sub-region ---
wa_sub = wa2.crop_array([[220020.0, 220080.0], [130020.0, 130060.0]])
print(f"crop_array : shape={wa_sub.nbx}x{wa_sub.nby}")

# --- merge: combine several arrays ---
h_left = header_wolf().make(orig=(0.0, 0.0), nb=(50, 40), d=(1.0, 1.0))
h_right = header_wolf().make(orig=(50.0, 0.0), nb=(50, 40), d=(1.0, 1.0))
a_left = WolfArrayModel(srcheader=h_left)
a_right = WolfArrayModel(srcheader=h_right)
merged = WolfArrayModel.merge([a_left, a_right])
print(f"merge      : shape={merged.nbx}x{merged.nby}")
_new_like  : shape=100x80, all zeros? False
crop_array : shape=60x40
merge      : shape=100x40

3. vector / vectorModel factories

Factory

Input

Notes

Constructor fromnumpy=

(N,2) or (N,3) array

In-constructor

Constructor fromlist=

List of tuples

In-constructor

Constructor fromshapely=

Shapely geometry

LineString or Polygon

make_from_numpy(arr)

Classmethod

Same as above, explicit name

make_from_list(lst)

Classmethod

Same as above, explicit name

make_from_shapely(obj)

Classmethod

Same as above, explicit name

deepcopy()

Instance

Full deep copy

[8]:
from wolfhece.PyVertexvectors import vector, wolfvertex

# --- From numpy array ---
coords = np.array([
    [220000.0, 130000.0],
    [220050.0, 130050.0],
    [220100.0, 130000.0],
])
v1 = vector(fromnumpy=coords, name='from_numpy')
print(f"from numpy  : {v1.myname}, {v1.nbvertices} vertices")

# --- From list of tuples ---
v2 = vector(fromlist=[(0, 0), (10, 20), (30, 10)], name='from_list')
print(f"from list   : {v2.myname}, {v2.nbvertices} vertices")

# --- From Shapely ---
from shapely.geometry import LineString
ls = LineString([(0, 0), (50, 50), (100, 0)])
v3 = vector(fromshapely=ls, name='from_shapely')
print(f"from shapely: {v3.myname}, {v3.nbvertices} vertices")

# --- Classmethod equivalents ---
v4 = vector.make_from_numpy(coords, name='classmethod_numpy')
print(f"classmethod : {v4.myname}, {v4.nbvertices} vertices")
from numpy  : from_numpy, 3 vertices
from list   : from_list, 3 vertices
from shapely: from_shapely, 3 vertices
classmethod : classmethod_numpy, 3 vertices
[9]:
# --- Vertex-by-vertex construction ---
v5 = vector(name='manual')
for x in np.linspace(0, 100, 11):
    v5.add_vertex(wolfvertex(x, 10.0 * np.sin(x / 15.0), 0.0))
print(f"manual      : {v5.nbvertices} vertices")

# --- Deep copy ---
v6 = v5.deepcopy(name='copied')
print(f"deepcopy    : {v6.myname}, {v6.nbvertices} vertices")

# --- Round-trip: vector <-> numpy <-> shapely ---
arr = v5.asnparray()         # -> (N, 2)
line = v5.asshapely_ls()     # -> LineString
print(f"as numpy    : shape={arr.shape}")
print(f"as shapely  : {line.geom_type}, length={line.length:.1f}")
manual      : 11 vertices
deepcopy    : copied, 11 vertices
as numpy    : shape=(11, 2)
as shapely  : LineString, length=110.5

4. zone / zoneModel factories

Factory

Input

Notes

Constructor fromshapely=

Shapely Polygon/MultiPolygon

Auto-imports geometry

add_vector(v)

Existing vector

Build zone programmatically

deepcopy()

Instance

Full deep copy with all vectors

[10]:
from wolfhece.PyVertexvectors import zone
from shapely.geometry import Polygon

# --- From Shapely polygon ---
poly = Polygon([(0, 0), (100, 0), (100, 50), (0, 50)])
z1 = zone(fromshapely=poly, name='from_shapely')
print(f"from shapely : {z1.myname}, {z1.nbvectors} vector(s)")

# --- Programmatic: create zone, add vectors ---
z2 = zone(name='built')
z2.add_vector(v1)  # reuse vector from above
z2.add_vector(v2)
print(f"built        : {z2.myname}, {z2.nbvectors} vector(s)")

# --- Deep copy ---
z3 = z2.deepcopy(name='copy_of_built')
print(f"deepcopy     : {z3.myname}, {z3.nbvectors} vector(s)")
from shapely : from_shapely, 1 vector(s)
built        : built, 2 vector(s)
deepcopy     : copy_of_built, 2 vector(s)

5. Zones / ZonesModel factories

Factory

Input

Notes

Constructor filename=

.vec, .vecz, .shp, .gpkg, .gdb, .dxf

Auto-detect format

import_shapefile(fn)

.shp path

With column / bbox filters

import_GeoDataFrame(gdf)

GeoDataFrame

From GeoPandas directly

import_dxf(fn)

.dxf path

AutoCAD import

import_gpkg(fn)

.gpkg path

GeoPackage

create_zone(name)

Add new empty zone

add_zone(z)

Existing zone

Append a zone

deepcopy()

Instance

Full deep copy

[12]:
from wolfhece.PyVertexvectors import Zones

# --- Build programmatically ---
zs = Zones()
new_zone = zs.create_zone(name='zone_A')
new_zone.add_vector(v1, forceparent=True)  # add vector to zone, and zone to zones (forceparent)

zs.add_zone(z1, forceparent=True)  # reuse zone from above
print(f"Zones: {zs.nbzones} zone(s)")

# --- Save as .vecz and reload ---
vecz_path = str(tmpdir / 'demo.vecz')
zs.saveas(vecz_path)

zs2 = Zones(filename=vecz_path)
print(f"Reloaded: {zs2.nbzones} zone(s)")
INFO:root:Finding min and max values
Zones: 2 zone(s)
Reloaded: 2 zone(s)
[13]:
# --- Round-trip via GeoDataFrame ---
gdf = zs.export_GeoDataFrame()
print(f"GeoDataFrame: {len(gdf)} rows")
print(gdf.head())

zs3 = Zones()
zs3.import_GeoDataFrame(gdf)
print(f"\nRe-imported: {zs3.nbzones} zone(s)")
INFO:root:Importing GeoDataFrame
INFO:root:Converting DataFrame into zones
GeoDataFrame: 2 rows
             id                                           geometry
0        zone_A  LINESTRING Z (220000 130000 -99999, 220050 130...
1  from_shapely          POLYGON ((0 0, 100 0, 100 50, 0 50, 0 0))

Re-imported: 2 zone(s)
[14]:
# --- Deep copy ---
zs_copy = zs.deepcopy()
print(f"Deep copy: {zs_copy.nbzones} zone(s)")
Deep copy: 2 zone(s)

Summary

Class

Quick creation

From file

From Shapely / numpy

Deep copy

header_wolf

make(orig, nb, d)

read_header(fn)

make_from_header(h)

WolfArray

WolfArray(srcheader=h)

WolfArray(fname=f)

np_source=arr

WolfArray(mold=wa)

vector

vector(name=n)

via parent Zones

fromnumpy=, fromshapely=

deepcopy()

zone

zone(name=n)

via parent Zones

fromshapely=

deepcopy()

Zones

Zones() + create_zone()

Zones(filename=f)

import_GeoDataFrame(gdf)

deepcopy()

See also: