Geometry: Add scenario support.

scenarios
Pierre-Antoine Rouby 2024-09-20 16:10:00 +02:00
parent 02c6430ed2
commit 4199eb6ac5
6 changed files with 133 additions and 114 deletions

View File

@ -203,7 +203,7 @@ class PointXYZ(Point, SQLSubModel):
owner_scenario=owner_scenario
)
if deleted:
nd.set_as_deleted()
new.set_as_deleted()
if sl == -1 or sl is None:
new._sl = None

View File

@ -32,10 +32,11 @@ class Profile(object):
rk: float = 0.0, name: str = "",
code1: int = 0, code2: int = 0,
_type: str = "", reach=None,
status=None):
super(Profile, self).__init__(id)
self._status = status
status=None, owner_scenario=-1):
super(Profile, self).__init__(
id=id, status=status,
owner_scenario=owner_scenario
)
self._num = int(num)
self._code1 = int(code1)
@ -64,7 +65,12 @@ class Profile(object):
if not isinstance(self._points, list):
self._points = self._get_points_list()
return self._points
return list(
filter(
lambda p: not p.is_deleted(),
self._points
)
)
def point(self, index):
return self.points[index]
@ -84,7 +90,7 @@ class Profile(object):
@num.setter
def num(self, value: int):
self._num = int(value)
self._status.modified()
self.modified()
@property
def code1(self):
@ -97,7 +103,7 @@ class Profile(object):
@code1.setter
def code1(self, value: int):
self._code1 = int(value)
self._status.modified()
self.modified()
@property
def code2(self):
@ -110,7 +116,7 @@ class Profile(object):
@code2.setter
def code2(self, value: int):
self._code2 = int(value)
self._status.modified()
self.modified()
@property
def nb_points(self):
@ -127,7 +133,7 @@ class Profile(object):
@rk.setter
def rk(self, value: float):
self._rk = float(value)
self._status.modified()
self.modified()
@property
def name(self):
@ -140,7 +146,7 @@ class Profile(object):
@name.setter
def name(self, value: str):
self._name = value.strip()
self._status.modified()
self.modified()
@property
def sl(self):
@ -153,7 +159,7 @@ class Profile(object):
@sl.setter
def sl(self, value):
self._sl = value
self._status.modified()
self.modified()
@property
def profile_type(self):
@ -166,7 +172,7 @@ class Profile(object):
@profile_type.setter
def profile_type(self, value: str):
self._profile_type = value
self._status.modified()
self.modified()
def point(self, i: int):
if i < len(self.points):
@ -193,21 +199,25 @@ class Profile(object):
Returns:
Nothing.
"""
self.points.insert(index, point)
self._status.modified()
if point in self._points:
point.set_as_not_deleted()
else:
self.points.insert(index, point)
self.modified()
def delete_i(self, indexes: list):
self._points = list(
list(
map(
lambda e: e[1],
lambda e: e[1].set_as_deleted(),
filter(
lambda e: e[0] not in indexes,
lambda e: e[0] in indexes,
enumerate(self.points)
)
)
)
self._status.modified()
self.modified()
def delete_points(self, points):
"""Delete some elements in profile list
@ -218,13 +228,13 @@ class Profile(object):
Returns:
Nothing.
"""
self._points = list(
filter(
lambda p: p not in points,
self.points
list(
map(
lambda p: p.set_as_deleted(),
points
)
)
self._status.modified()
self.modified()
# Move
@ -234,7 +244,7 @@ class Profile(object):
p = self.points
p[index], p[next] = p[next], p[index]
self._status.modified()
self.modified()
def move_down_point(self, index: int):
if index >= 0:
@ -242,7 +252,7 @@ class Profile(object):
p = self.points
p[index], p[prev] = p[prev], p[index]
self._status.modified()
self.modified()
# Sort
@ -259,7 +269,7 @@ class Profile(object):
key=predicate,
reverse=is_reversed
)
self._status.modified()
self.modified()
@timer
def sort_with_indexes(self, indexes: list):
@ -275,12 +285,12 @@ class Profile(object):
)
)
)
self._status.modified()
self.modified()
@timer
def reverse(self):
self._points.reverse()
self._status.modified()
self.modified()
# Sediment Layers

View File

@ -47,7 +47,7 @@ class ProfileXYZ(Profile, SQLSubModel):
num=0,
nb_point: int = 0,
code1: int = 0, code2: int = 0,
status=None):
status=None, owner_scenario=-1):
"""ProfileXYZ constructor
Args:
@ -69,6 +69,7 @@ class ProfileXYZ(Profile, SQLSubModel):
_type="XYZ",
reach=reach,
status=status,
owner_scenario=owner_scenario
)
@classmethod
@ -76,6 +77,7 @@ class ProfileXYZ(Profile, SQLSubModel):
execute(f"""
CREATE TABLE geometry_profileXYZ{ext} (
{cls.create_db_add_pamhyr_id()},
deleted BOOLEAN NOT NULL DEFAULT FALSE,
ind INTEGER NOT NULL,
name TEXT,
reach INTEGER NOT NULL,
@ -121,6 +123,13 @@ class ProfileXYZ(Profile, SQLSubModel):
cls._db_update_to_0_1_0(execute, data)
if major == "0" and minor == "1":
if int(release) < 2:
execute(
"ALTER TABLE geometry_profileXYZ " +
"ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE"
)
return cls._update_submodel(execute, version, data)
@classmethod
@ -194,35 +203,47 @@ class ProfileXYZ(Profile, SQLSubModel):
@classmethod
def _db_load(cls, execute, data=None):
profiles = []
status = data["status"]
scenario = data["scenario"]
loaded = data['loaded_pid']
reach = data["reach"]
if scenario is None:
return
table = execute(
"SELECT pamhyr_id, name, rk, num, code1, code2, sl " +
"SELECT pamhyr_id, deleted, name, rk, num, " +
"code1, code2, sl, scenario " +
"FROM geometry_profileXYZ " +
f"WHERE reach = {reach.id} " +
f"AND scenario = {scenario.id} " +
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) " +
"ORDER BY ind ASC"
)
for row in table:
it = iter(row)
id = next(it)
pid = next(it)
deleted = (next(it) == 1)
name = next(it)
rk = next(it)
num = next(it)
code1 = next(it)
code2 = next(it)
sl = next(it)
owner_scenario = next(it)
new = cls(
id=id, num=num,
id=pid, num=num,
name=name, rk=rk,
code1=code1, code2=code2,
reach=reach,
status=status
status=status,
owner_scenario=owner_scenario
)
if deleted:
new.set_as_deleted()
if sl == -1 or sl is None:
new._sl = None
@ -237,9 +258,17 @@ class ProfileXYZ(Profile, SQLSubModel):
data["profile"] = new
new._points = PointXYZ._db_load(execute, data.copy())
loaded.add(pid)
yield new
data["scenario"] = scenario.parent
yield from cls._db_load(execute, data)
data["scenario"] = scenario
def _db_save(self, execute, data=None):
if not self.must_be_saved():
return True
ok = True
ind = data["ind"]
@ -247,25 +276,25 @@ class ProfileXYZ(Profile, SQLSubModel):
execute(
"INSERT OR REPLACE INTO " +
"geometry_profileXYZ(pamhyr_id, ind, name, reach, " +
"rk, num, code1, code2, sl) " +
"geometry_profileXYZ(pamhyr_id, deleted, ind, name, reach, " +
"rk, num, code1, code2, sl, scenario) " +
"VALUES (" +
f"{self.pamhyr_id}, {ind}, '{self._db_format(self._name)}', " +
f"{self.pamhyr_id}, {self._db_format(self.is_deleted())}, " +
f"{ind}, '{self._db_format(self._name)}', " +
f"{self.reach.pamhyr_id}, {self.rk}, {self.num}, " +
f"{self.code1}, {self.code1}, {sl}" +
f"{self.code1}, {self.code1}, {sl}, {self._status.scenario_id}" +
")"
)
points = self.points
data["profile"] = self
execute(
"DELETE FROM geometry_pointXYZ " +
f"WHERE profile = {self.pamhyr_id}"
f"WHERE profile = {self.pamhyr_id} " +
f"AND scenario = {self._status.scenario_id}"
)
ind = 0
for point in points:
for point in self._points:
data["ind"] = ind
ok &= point._db_save(execute, data)
ind += 1
@ -380,7 +409,7 @@ class ProfileXYZ(Profile, SQLSubModel):
for point in list_points:
pt = PointXYZ(*point, profile=self, status=self._status)
self.points.append(pt)
self._status.modified()
self.modified()
def get_point_i(self, index: int) -> PointXYZ:
"""Get point at index.
@ -441,7 +470,7 @@ class ProfileXYZ(Profile, SQLSubModel):
"""
point_xyz = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.append(point_xyz)
self._status.modified()
self.modified()
def insert(self, index: int):
"""Insert a new point at index.
@ -454,7 +483,7 @@ class ProfileXYZ(Profile, SQLSubModel):
"""
point = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.insert(index, point)
self._status.modified()
self.modified()
return point
def filter_isnan(self, lst):

View File

@ -80,15 +80,14 @@ class Reach(SQLSubModel):
return new
def _db_save(self, execute, data=None):
profiles = self.profiles
execute(
"DELETE FROM geometry_profileXYZ " +
f"WHERE reach = {self.pamhyr_id}"
f"WHERE reach = {self.pamhyr_id} " +
f"AND scenario = {self._status.scenario_id}"
)
ind = 0
for profile in profiles:
for profile in self._profiles:
data["ind"] = ind
profile._db_save(execute, data)
ind += 1
@ -121,17 +120,14 @@ class Reach(SQLSubModel):
return list(self._profiles)
def __len__(self):
if not isinstance(self._profiles, list):
self._profiles = self._get_profiles_list()
return len(self._profiles)
return len(self.profiles)
@property
def profiles(self):
if not isinstance(self._profiles, list):
self._profiles = self._get_profiles_list()
return self._profiles
return list(filter(lambda p: not p.is_deleted(), self._profiles))
@profiles.setter
def profiles(self, profiles):
@ -159,15 +155,6 @@ class Reach(SQLSubModel):
"""
return self.profiles
def _update_profile_numbers(self):
"""Update profiles index
Returns:
Nothing.
"""
for ind, profile in enumerate(self.get_geometry()):
profile.num = ind + 1
def insert(self, index: int):
"""Insert new profile in list
@ -180,9 +167,8 @@ class Reach(SQLSubModel):
profile = ProfileXYZ(reach=self, status=self._status)
self.profiles.insert(index, profile)
self._update_profile_numbers()
self._status.modified()
self.modified()
return profile
@ -195,9 +181,12 @@ class Reach(SQLSubModel):
Returns:
Nothing.
"""
self.profiles.insert(index, profile)
self._update_profile_numbers()
self._status.modified()
if profile in self._profiles:
self.undelete([profile])
else:
self.profiles.insert(index, profile)
self.modified()
def delete(self, indexes):
"""Delete some elements in profile list
@ -208,24 +197,16 @@ class Reach(SQLSubModel):
Returns:
Nothing.
"""
profiles = set(
list(
map(
lambda e: e[1],
lambda p: p[1].set_as_deleted(),
filter(
lambda e: e[0] in indexes,
enumerate(self.profiles)
)
)
)
self._profiles = list(
filter(
lambda p: p not in profiles,
self.profiles
)
)
self._update_profile_numbers()
self._status.modified()
self.modified()
def delete_profiles(self, profiles):
"""Delete some elements in profile list
@ -236,19 +217,24 @@ class Reach(SQLSubModel):
Returns:
Nothing.
"""
self._profiles = list(
filter(
lambda p: p not in profiles,
self.profiles
list(
map(
lambda p: p.set_as_deleted(),
profiles
)
)
self._update_profile_numbers()
self._status.modified()
self.modified()
def undelete(self, lst):
for el in lst:
el.set_as_not_deleted()
self.modified()
def purge(self):
self._profiles = []
self._update_profile_numbers()
self._status.modified()
for el in self._profiles:
el.set_as_deleted()
self.modified()
def move_up_profile(self, index: int):
if index < len(self.profiles):
@ -256,7 +242,7 @@ class Reach(SQLSubModel):
p = self.profiles
p[index], p[next] = p[next], p[index]
self._status.modified()
self.modified()
def move_down_profile(self, index: int):
if index >= 0:
@ -264,7 +250,7 @@ class Reach(SQLSubModel):
p = self.profiles
p[index], p[prev] = p[prev], p[index]
self._status.modified()
self.modified()
def get_x(self):
return list(
@ -489,7 +475,7 @@ class Reach(SQLSubModel):
self._compute_guidelines_cache(guide_set, named_points,
complete, incomplete)
self._status.modified()
self.modified()
return (complete, incomplete)
def _map_guidelines_points(self, func, full=False):
@ -535,7 +521,7 @@ class Reach(SQLSubModel):
key=lambda profile: profile.rk,
reverse=is_reversed
)
self._status.modified()
self.modified()
@timer
def sort_with_indexes(self, indexes: list):
@ -551,7 +537,7 @@ class Reach(SQLSubModel):
)
)
)
self._status.modified()
self.modified()
# Import/Export
@ -608,7 +594,6 @@ class Reach(SQLSubModel):
profiles.append(prof)
self.profiles = profiles + self.profiles
self._update_profile_numbers()
self._recompute_rk()
return profiles
@ -643,7 +628,7 @@ class Reach(SQLSubModel):
prof.import_points(profile)
imported_profiles.append(prof)
self._status.modified()
self.modified()
except FileNotFoundError as e:
logger.error(e)
exception_message_box(e)
@ -653,7 +638,6 @@ class Reach(SQLSubModel):
finally:
self.profiles = imported_profiles + self.profiles
self._update_profile_numbers()
return imported_profiles
@timer

View File

@ -93,7 +93,7 @@ class AddCommand(QUndoCommand):
self._point = None
def undo(self):
self._profile.delete_i([self._index])
self._profile.delete_point([self._point])
def redo(self):
if self._point is None:
@ -111,15 +111,13 @@ class DelCommand(QUndoCommand):
self._points = []
for row in rows:
self._points.append((row, self._profile.point(row)))
self._points.sort() # Sort by row index
self._points.append(self._profile.point(row))
def undo(self):
for row, point in self._points:
self._profile.insert_point(row, point)
self._profile.undelete(self._points)
def redo(self):
self._profile.delete_i(self._rows)
self._profile.delete(self._points)
class SortCommand(QUndoCommand):

View File

@ -95,15 +95,13 @@ class DelCommand(QUndoCommand):
self._profiles = []
for row in rows:
self._profiles.append((row, self._reach.profile(row)))
self._profiles.sort()
self._profiles.append(self._reach.profile(row))
def undo(self):
for row, profile in self._profiles:
self._reach.insert_profile(row, profile)
self._reach.undelete(self._profiles)
def redo(self):
self._reach.delete(self._rows)
self._reach.delete_profiles(self._profiles)
class SortCommand(QUndoCommand):
@ -300,13 +298,13 @@ class ShiftCommand(QUndoCommand):
def undo(self):
for i in self._rows:
profile = self._reach.profiles[i]
self._reach.profiles[i].shift(-self._dx,
-self._dy,
-self._dz)
self._reach.profiles[i].shift(
-self._dx, -self._dy, -self._dz
)
def redo(self):
for i in self._rows:
profile = self._reach.profiles[i]
self._reach.profiles[i].shift(self._dx,
self._dy,
self._dz)
self._reach.profiles[i].shift(
self._dx, self._dy, self._dz
)