Closed icassina closed 6 years ago
Hi @icassina I'm not familiar with postgis' topology, need some time to learn it.
BTW, to use it in Scala project, which Java/Scala type is a good candidate for type mapper?
That is the major problem, in my opinion.
TopoGeometry is a special type, containing information about the topology and layer to look for, and the features.. i'm not very familiar myself. However, on retrieval, it's transparently casted to the corresponding (multi) geometry.
The mechanism would be like this (it's complicated, that's why it takes a slick "master" to tackle it):
example:
case class MyFeat(id: Long, line: MultiLineString, attr1: String)
class MyFeatTable(tag: Tag) extends Table[MyFeat](tag, Some("public"), "feats") with Topology {
/* the Topology mix-in should do steps 1), 2) and 3) on table creation */
def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
def attr1 = column[String]("attr1")
def lines = column[TopoGeom[MultiLineString]]("lines") // using columns of topoGeom
/* maybe is easier with:
def lines = topoGeomColumn[MultiLineString]("lines")
*/
def * = (id, lines, attr1) <> (
/* (select) here maybe the query should do an explicit cast with '::geometry' */,
/* (insert) here the query should wrap (lines) into that toTopoGeom() postgis function */
)
}
@cvogt @szeiger hey guys, what do you think of the approach @icassina suggest? do you guys know some client who actually had to deal with such stuff? ty!
mmm you should add this to the MyFeatTable definition (to comply with the hypotetic Topology trait):
{
…
val topology_name = "my_feats_topology"
}
I haven't run into this myself yet. How closely are those topology types related to relational tables? From what I see here in the original sketch, it looks more like a special feature, so maybe it should be implemented with a different API, likes sequences?
Hi @icassina sorry for my slow response!
I'm busy on company's project these days, and will still be busy in next several weeks.
I did some learning and trying about postgis topology, and here's some problems and results:
TopoGeometry
/TopoElement
/TopoElementArray
, so maybe we need create oursTopoGeometry
is a composite type, and its output is a four tuple, like (1,1,4,1)
, but many functions required topology parameter is the topology name, so we need get topology name by topology_id when we want to do some topology operations based on a topogeometryGetTopologyName
to help us to get topology name, but there still is an associated problem: currently slick-pg
built-in composite type support is NOT powerful enough to allow us to construct a COLUMN by accessing a composite type COLUMN's field, so using slick/slick-pg
I can't express GetTopologyName((my_topo_geom).topology_id)
slick-pg
doesn't support row/record type currently, so I can't implement getfaceedges_returntype
, and some functions' implementaton, like ST_GetFaceEdges
/GetRingEdges
/GetNodeEdges
, will be impacted.I'll keep learning and trying.
topology.topology
contains that information. GetTopologyName
probably just SELECT
on that table.Thank you very much. slick-pg
would be the first library implementing seamless access to postgis topology!
@szeiger each topology is stored in their own schema. This is done by using special postgis functions, as described above.
The primary benefit of using topologies is that whenever you add a new geometry element to it, it will:
It also allows to:
This implies also that when you add a geometry to a topology using the above method (toTopoGeom
), and that geometry is on (or snapped on) an existing LineString
(for example), then, when retrieving that LineString
(which has some attributes associated, see above) you will retrieve a MultiLineString
instead, as it was splitted in the process. Both parts of the MultiLineString
will still have the original attributes associated. Even lines that weren't splitted will be retrieved as MultiLineString
, but with only a single part.
The author of these postgis functionalities told me about the undocumented valid values of the feature_type
argument of the topology.AddTopoGeometryColumn
function (the values used internally), which tackle a bit better their nature. Behaviour does not change but it allow us to think about the nature of what we're working with:
POINT
, use puntal
(i.e. 0-dimension geometries: Point in, MultiPoint out)LINE
, use lineal
(i.e. 1-dimension geometries: LineString in, MultiLineString out)POLYGON
use areal
(i.e. 2-dimension geometries: Polygon in, MultiPolygon out)reference: https://github.com/postgis/postgis/blob/svn-trunk/topology/sql/topogeometry/totopogeom.sql.in
postgis also supports mixed
type, for hierarchical layers, but I've not yet experimented with it. Taking this into account it would be more like a tree than a linear sequence (but Tree is a collection and share the API anyway).
Hi @icassina just a little update. I already started working on this, but haven't any code changes submitted yet.
I know is very hard (i'm trying right now but I don't know slick well enough yet), but it would be quite nice to have topology support integrated into slick-pg.
Basically, if you want to have a topology with, let's say, points and lines with attributes you would proceed like this:
1) create the topology
It will create a new schema named "my_topology_name" and with four tables in it:
It will also store the metadata into
topology.topology
.2) create your edges and nodes tables
3) add TopoGeometry columns to these tables
It's a special kind of column, that, on insert, will add geometries to the topology (splitting and snapping as needed), and on retrival, will get geometries from the topology.
The result of the select is the layer_id to use with
topology.toTopoGeom()
(next section). Let's say thatmy_edges.line
has a layer_id of 1 andmy_nodes.point
has a layer_id of 2.Note: on retrival, the type of the geometry will be Multi
Geometry
(i.e.LineString
->MultiLineString
,Point
->MultiPoint
) since splitting might have occurred!!4) insert features
5) retrieve features
Note: the TopoGeometry column will be automatically casted to a Geometry.
For my_edges you'll get the id, a MultiLineString and a varchar.
For my_nodes you'll get the id, a MultiPoint and a varchar.