mirror of https://gitlab.com/pamhyr/pamhyr2
Geometry: Add scenario support.
parent
02c6430ed2
commit
4199eb6ac5
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue