Skip to content

Commit

Permalink
Always write fid index of Node and Edge tables (#995)
Browse files Browse the repository at this point in the history
We are using `GeoDataFrame.to_file` to write these tables to GeoPackage.
By default GeoPandas only writes the index if it has a name. We don't
want to rely on users naming indices, so this sets the name and ensure
it is written.

I ran into this since I noticed the `model.network.edge.df.index` (by
default 0-based) did not correspond to the 1-based fid column that
GeoPandas writes.


https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.to_file.html
  • Loading branch information
visr authored Jan 26, 2024
1 parent f4e90ad commit 8a9a928
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
6 changes: 3 additions & 3 deletions core/test/validation_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ end
@test logger.logs[3].kwargs[:control_state] == ""
@test logger.logs[4].level == Error
@test logger.logs[4].message == "Cannot connect a basin to a fractional_flow."
@test logger.logs[4].kwargs[:edge_id] == 7
@test logger.logs[4].kwargs[:edge_id] == 6
@test logger.logs[4].kwargs[:id_src] == NodeID(2)
@test logger.logs[4].kwargs[:id_dst] == NodeID(8)
end
Expand Down Expand Up @@ -358,10 +358,10 @@ end
@test length(logger.logs) == 2
@test logger.logs[1].level == Error
@test logger.logs[1].message ==
"Invalid edge type 'foo' for edge #1 from node #1 to node #2."
"Invalid edge type 'foo' for edge #0 from node #1 to node #2."
@test logger.logs[2].level == Error
@test logger.logs[2].message ==
"Invalid edge type 'bar' for edge #2 from node #2 to node #3."
"Invalid edge type 'bar' for edge #1 from node #2 to node #3."
end

@testitem "Subgrid validation" begin
Expand Down
3 changes: 2 additions & 1 deletion python/ribasim/ribasim/input_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,9 @@ def _write_table(self, path: FilePath) -> None:

gdf = gpd.GeoDataFrame(data=self.df)
gdf = gdf.set_geometry("geometry")
gdf.index.name = "fid"

gdf.to_file(path, layer=self.tablename(), driver="GPKG")
gdf.to_file(path, layer=self.tablename(), driver="GPKG", index=True)

def sort(self):
self.df.sort_index(inplace=True)
Expand Down
27 changes: 25 additions & 2 deletions python/ribasim/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,33 @@ def test_plot(discrete_control_of_pid_control):

def test_write_adds_fid_in_tables(basic, tmp_path):
model_orig = basic
# for node an explicit index was provided
nrow = len(model_orig.network.node.df)
assert model_orig.network.node.df.index.name == "fid"
assert model_orig.network.node.df.index.equals(
pd.RangeIndex(start=1, stop=nrow + 1)
)
# for edge no index was provided, but it still needs to write it to file
nrow = len(model_orig.network.edge.df)
assert model_orig.network.edge.df.index.name is None
assert model_orig.network.edge.df.index.equals(pd.RangeIndex(start=0, stop=nrow))

model_orig.write(tmp_path / "basic/ribasim.toml")
with connect(tmp_path / "basic/database.gpkg") as connection:
query = f"select * from {esc_id('Basin / profile')}"
df = pd.read_sql_query(query, connection, parse_dates=["time"])
df = pd.read_sql_query(query, connection)
assert "fid" in df.columns
fids = df.get("fid")
fids = df["fid"]
assert fids.equals(pd.Series(range(1, len(fids) + 1)))

query = "select fid from Node"
df = pd.read_sql_query(query, connection)
assert "fid" in df.columns
fids = df["fid"]
assert fids.equals(pd.Series(range(1, len(fids) + 1)))

query = "select fid from Edge"
df = pd.read_sql_query(query, connection)
assert "fid" in df.columns
fids = df["fid"]
assert fids.equals(pd.Series(range(0, len(fids))))

0 comments on commit 8a9a928

Please sign in to comment.