diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 7593067c9..41938c618 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -311,6 +311,11 @@ const db::EdgePair *DeepEdgePairs::nth (size_t) const throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat edge pair collections"))); } +db::properties_id_type DeepEdgePairs::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat edge pair collections"))); +} + bool DeepEdgePairs::has_valid_edge_pairs () const { return false; diff --git a/src/db/db/dbDeepEdgePairs.h b/src/db/db/dbDeepEdgePairs.h index c55e7f97f..7ed036d6e 100644 --- a/src/db/db/dbDeepEdgePairs.h +++ b/src/db/db/dbDeepEdgePairs.h @@ -70,6 +70,7 @@ public: virtual Box bbox () const; virtual bool empty () const; virtual const db::EdgePair *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; virtual void apply_property_translator (const db::PropertiesTranslator &pt); diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index bd80f7ac9..3872386fe 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -438,6 +438,12 @@ DeepEdges::nth (size_t /*n*/) const throw tl::Exception (tl::to_string (tr ("Random access to edges is available only for flat edge collections"))); } +db::properties_id_type +DeepEdges::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to edges is available only for flat collections"))); +} + bool DeepEdges::has_valid_edges () const { diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index 6af2bf55a..b8cf9fc2e 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -76,6 +76,7 @@ public: virtual bool is_merged () const; virtual const db::Edge *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edges () const; virtual bool has_valid_merged_edges () const; diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index 271777473..0cffe8960 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -678,7 +678,7 @@ public: /** * @brief Returns the nth edge pair * - * This operation is available only for flat regions - i.e. such for which + * This operation is available only for flat edge pair collections - i.e. such for which * "has_valid_edge_pairs" is true. */ const db::EdgePair *nth (size_t n) const @@ -686,6 +686,17 @@ public: return mp_delegate->nth (n); } + /** + * @brief Returns the nth edge pair's property ID + * + * This operation is available only for flat edge pair collections - i.e. such for which + * "has_valid_edge_pairs" is true. + */ + db::properties_id_type nth_prop_id (size_t n) const + { + return mp_delegate->nth_prop_id (n); + } + /** * @brief Forces flattening of the edge pair collection * diff --git a/src/db/db/dbEdgePairsDelegate.h b/src/db/db/dbEdgePairsDelegate.h index d8dd18849..d4a1efd97 100644 --- a/src/db/db/dbEdgePairsDelegate.h +++ b/src/db/db/dbEdgePairsDelegate.h @@ -273,6 +273,7 @@ public: virtual EdgePairsDelegate *in (const EdgePairs &other, bool invert) const = 0; virtual const db::EdgePair *nth (size_t n) const = 0; + virtual db::properties_id_type nth_prop_id (size_t n) const = 0; virtual bool has_valid_edge_pairs () const = 0; virtual const db::RecursiveShapeIterator *iter () const = 0; diff --git a/src/db/db/dbEdges.h b/src/db/db/dbEdges.h index 6b507048a..31bdc35af 100644 --- a/src/db/db/dbEdges.h +++ b/src/db/db/dbEdges.h @@ -1440,13 +1440,24 @@ public: /** * @brief Returns the nth edge * - * This operation is available only for flat regions - i.e. such for which "has_valid_edges" is true. + * This operation is available only for flat edge collections - i.e. such for which "has_valid_edges" is true. */ const db::Edge *nth (size_t n) const { return mp_delegate->nth (n); } + /** + * @brief Returns the nth edge's property ID + * + * This operation is available only for flat edge collections - i.e. such for which + * "has_valid_edges" is true. + */ + db::properties_id_type nth_prop_id (size_t n) const + { + return mp_delegate->nth_prop_id (n); + } + /** * @brief Forces flattening of the edge collection * diff --git a/src/db/db/dbEdgesDelegate.h b/src/db/db/dbEdgesDelegate.h index 496b86931..91aea92ee 100644 --- a/src/db/db/dbEdgesDelegate.h +++ b/src/db/db/dbEdgesDelegate.h @@ -280,6 +280,7 @@ public: virtual std::pair in_and_out (const Edges &) const = 0; virtual const db::Edge *nth (size_t n) const = 0; + virtual db::properties_id_type nth_prop_id (size_t n) const = 0; virtual bool has_valid_edges () const = 0; virtual bool has_valid_merged_edges () const = 0; diff --git a/src/db/db/dbEmptyEdgePairs.h b/src/db/db/dbEmptyEdgePairs.h index f63cfd1a8..92650b923 100644 --- a/src/db/db/dbEmptyEdgePairs.h +++ b/src/db/db/dbEmptyEdgePairs.h @@ -89,6 +89,7 @@ public: virtual EdgePairsDelegate *in (const EdgePairs &, bool) const { return new EmptyEdgePairs (); } virtual const db::EdgePair *nth (size_t) const { tl_assert (false); } + virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); } virtual bool has_valid_edge_pairs () const { return true; } virtual const db::RecursiveShapeIterator *iter () const { return 0; } diff --git a/src/db/db/dbEmptyEdges.h b/src/db/db/dbEmptyEdges.h index 84032b448..bf45753cd 100644 --- a/src/db/db/dbEmptyEdges.h +++ b/src/db/db/dbEmptyEdges.h @@ -119,6 +119,7 @@ public: virtual std::pair in_and_out (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); } virtual const db::Edge *nth (size_t) const { tl_assert (false); } + virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); } virtual bool has_valid_edges () const { return true; } virtual bool has_valid_merged_edges () const { return true; } diff --git a/src/db/db/dbFlatEdgePairs.cc b/src/db/db/dbFlatEdgePairs.cc index cb554a3ea..a42bce475 100644 --- a/src/db/db/dbFlatEdgePairs.cc +++ b/src/db/db/dbFlatEdgePairs.cc @@ -173,7 +173,46 @@ EdgePairsDelegate *FlatEdgePairs::add_in_place (const EdgePairs &other) const db::EdgePair *FlatEdgePairs::nth (size_t n) const { - return n < mp_edge_pairs->size () ? &mp_edge_pairs->get_layer ().begin () [n] : 0; + // NOTE: this assumes that we iterate over non-property edge pairs first and then over edges with properties + + if (n >= mp_edge_pairs->size ()) { + return 0; + } + + const db::layer &l = mp_edge_pairs->get_layer (); + if (n < l.size ()) { + return &l.begin () [n]; + } + n -= l.size (); + + const db::layer &lp = mp_edge_pairs->get_layer (); + if (n < lp.size ()) { + return &lp.begin () [n]; + } + + return 0; +} + +db::properties_id_type FlatEdgePairs::nth_prop_id (size_t n) const +{ + // NOTE: this assumes that we iterate over non-property edge pairs first and then over edges with properties + + if (n >= mp_edge_pairs->size ()) { + return 0; + } + + const db::layer &l = mp_edge_pairs->get_layer (); + if (n < l.size ()) { + return 0; + } + n -= l.size (); + + const db::layer &lp = mp_edge_pairs->get_layer (); + if (n < lp.size ()) { + return lp.begin () [n].properties_id (); + } + + return 0; } bool FlatEdgePairs::has_valid_edge_pairs () const diff --git a/src/db/db/dbFlatEdgePairs.h b/src/db/db/dbFlatEdgePairs.h index dc38dc088..ce203c4aa 100644 --- a/src/db/db/dbFlatEdgePairs.h +++ b/src/db/db/dbFlatEdgePairs.h @@ -75,6 +75,7 @@ public: virtual EdgePairsDelegate *add (const EdgePairs &other) const; virtual const db::EdgePair *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; diff --git a/src/db/db/dbFlatEdges.cc b/src/db/db/dbFlatEdges.cc index 44299bc8c..27e323cae 100644 --- a/src/db/db/dbFlatEdges.cc +++ b/src/db/db/dbFlatEdges.cc @@ -361,7 +361,46 @@ EdgesDelegate *FlatEdges::add_in_place (const Edges &other) const db::Edge *FlatEdges::nth (size_t n) const { - return n < mp_edges->size () ? &mp_edges->get_layer ().begin () [n] : 0; + // NOTE: this assumes that we iterate over non-property edges first and then over edges with properties + + if (n >= mp_edges->size ()) { + return 0; + } + + const db::layer &l = mp_edges->get_layer (); + if (n < l.size ()) { + return &l.begin () [n]; + } + n -= l.size (); + + const db::layer &lp = mp_edges->get_layer (); + if (n < lp.size ()) { + return &lp.begin () [n]; + } + + return 0; +} + +db::properties_id_type FlatEdges::nth_prop_id (size_t n) const +{ + // NOTE: this assumes that we iterate over non-property polygons first and then over polygons with properties + + if (n >= mp_edges->size ()) { + return 0; + } + + const db::layer &l = mp_edges->get_layer (); + if (n < l.size ()) { + return 0; + } + n -= l.size (); + + const db::layer &lp = mp_edges->get_layer (); + if (n < lp.size ()) { + return lp.begin () [n].properties_id (); + } + + return 0; } bool FlatEdges::has_valid_edges () const diff --git a/src/db/db/dbFlatEdges.h b/src/db/db/dbFlatEdges.h index f5464be30..551c33ce4 100644 --- a/src/db/db/dbFlatEdges.h +++ b/src/db/db/dbFlatEdges.h @@ -89,6 +89,7 @@ public: virtual EdgesDelegate *add (const Edges &other) const; virtual const db::Edge *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edges () const; virtual bool has_valid_merged_edges () const; diff --git a/src/db/db/dbOriginalLayerEdgePairs.cc b/src/db/db/dbOriginalLayerEdgePairs.cc index 301208ebc..5038a1885 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.cc +++ b/src/db/db/dbOriginalLayerEdgePairs.cc @@ -190,6 +190,12 @@ OriginalLayerEdgePairs::nth (size_t) const throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat collections"))); } +db::properties_id_type +OriginalLayerEdgePairs::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat collections"))); +} + bool OriginalLayerEdgePairs::has_valid_edge_pairs () const { diff --git a/src/db/db/dbOriginalLayerEdgePairs.h b/src/db/db/dbOriginalLayerEdgePairs.h index bcecf1f7c..41000da51 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.h +++ b/src/db/db/dbOriginalLayerEdgePairs.h @@ -53,6 +53,7 @@ public: virtual bool empty () const; virtual const db::EdgePair *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index a01314308..3484b926e 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -233,6 +233,12 @@ OriginalLayerEdges::nth (size_t) const throw tl::Exception (tl::to_string (tr ("Random access to edges is available only for flat collections"))); } +db::properties_id_type +OriginalLayerEdges::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to edges is available only for flat collections"))); +} + bool OriginalLayerEdges::has_valid_edges () const { diff --git a/src/db/db/dbOriginalLayerEdges.h b/src/db/db/dbOriginalLayerEdges.h index 89d6fc647..53254e852 100644 --- a/src/db/db/dbOriginalLayerEdges.h +++ b/src/db/db/dbOriginalLayerEdges.h @@ -58,6 +58,7 @@ public: virtual bool is_merged () const; virtual const db::Edge *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_edges () const; virtual bool has_valid_merged_edges () const; diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index 282c917a8..903aba802 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -789,8 +789,7 @@ static tl::Variant nth (const db::EdgePairs *edge_pairs, size_t n) if (! ep) { return tl::Variant (); } else { - // @@@ return tl::Variant (db::EdgePairWithProperties (*ep, edge_pairs->nth_prop_id (n))); - return tl::Variant (); // @@@ + return tl::Variant (db::EdgePairWithProperties (*ep, edge_pairs->nth_prop_id (n))); } } diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index 3eb98edc0..0383d14ac 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -854,8 +854,7 @@ static tl::Variant nth (const db::Edges *edges, size_t n) if (! e) { return tl::Variant (); } else { - // @@@ return tl::Variant (db::EdgeWithProperties (*e, edges->nth_prop_id (n))); - return tl::Variant (); // @@@ + return tl::Variant (db::EdgeWithProperties (*e, edges->nth_prop_id (n))); } } diff --git a/src/db/unit_tests/dbEdgePairsTests.cc b/src/db/unit_tests/dbEdgePairsTests.cc index 1f6153c3d..1a8680fdd 100644 --- a/src/db/unit_tests/dbEdgePairsTests.cc +++ b/src/db/unit_tests/dbEdgePairsTests.cc @@ -279,3 +279,24 @@ TEST(6_add_with_properties) EXPECT_EQ ((ro1 + rf2).to_string (), "(10,20;-20,60)/(10,30;-20,70){net=>17};(-10,20;20,60)/(-10,30;20,70){net=>17}"); } +TEST(7_properties) +{ + db::PropertiesSet ps; + + ps.insert (tl::Variant ("id"), 1); + db::properties_id_type pid1 = db::properties_id (ps); + + db::EdgePairs edge_pairs; + db::Edge e1 (db::Point (0, 0), db::Point (10, 20)); + db::Edge e2 (db::Point (1, 2), db::Point (11, 22)); + edge_pairs.insert (db::EdgePairWithProperties (db::EdgePair (e1, e2), pid1)); + edge_pairs.insert (db::EdgePair (e1, e2)); + + EXPECT_EQ (edge_pairs.nth (0)->to_string (), "(0,0;10,20)/(1,2;11,22)"); + EXPECT_EQ (edge_pairs.nth (1)->to_string (), "(0,0;10,20)/(1,2;11,22)"); + EXPECT_EQ (edge_pairs.nth (2) == 0, true); + + EXPECT_EQ (edge_pairs.nth_prop_id (0), db::properties_id_type (0)); + EXPECT_EQ (edge_pairs.nth_prop_id (1), pid1); +} + diff --git a/src/db/unit_tests/dbEdgesTests.cc b/src/db/unit_tests/dbEdgesTests.cc index 15a4b562b..0db2b9676 100644 --- a/src/db/unit_tests/dbEdgesTests.cc +++ b/src/db/unit_tests/dbEdgesTests.cc @@ -1443,6 +1443,25 @@ TEST(32_add_with_properties) EXPECT_EQ ((ro1 + rf2).to_string (), "(10,20;40,60){net=>17};(-10,20;20,60){net=>17}"); } +TEST(33_properties) +{ + db::PropertiesSet ps; + + ps.insert (tl::Variant ("id"), 1); + db::properties_id_type pid1 = db::properties_id (ps); + + db::Edges edges; + edges.insert (db::EdgeWithProperties (db::Edge (db::Point (0, 0), db::Point (10, 20)), pid1)); + edges.insert (db::Edge (db::Point (0, 0), db::Point (10, 20))); + + EXPECT_EQ (edges.nth (0)->to_string (), "(0,0;10,20)"); + EXPECT_EQ (edges.nth (1)->to_string (), "(0,0;10,20)"); + EXPECT_EQ (edges.nth (2) == 0, true); + + EXPECT_EQ (edges.nth_prop_id (0), db::properties_id_type (0)); + EXPECT_EQ (edges.nth_prop_id (1), pid1); +} + // GitHub issue #72 (Edges/Region NOT issue) TEST(100) { diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb index d67bc33c6..ac157ff53 100644 --- a/testdata/ruby/dbEdgePairsTest.rb +++ b/testdata/ruby/dbEdgePairsTest.rb @@ -111,7 +111,7 @@ class DBEdgePairs_TestClass < TestBase assert_equal(csort(r.edges.to_s), csort("(0,0;0,100);(-10,0;-20,50)")) assert_equal(r.is_empty?, false) assert_equal(r.size, 1) - assert_equal(r[0].to_s, "(0,0;0,100)/(-10,0;-20,50)") + assert_equal(r[0].to_s, "(0,0;0,100)/(-10,0;-20,50) props={}") assert_equal(r[1].to_s, "") assert_equal(r.bbox.to_s, "(-20,0;0,100)") @@ -221,7 +221,7 @@ class DBEdgePairs_TestClass < TestBase r.flatten assert_equal(r.has_valid_edge_pairs?, true) - assert_equal(r[1].to_s, "(0,101;2,103)/(10,111;12,113)") + assert_equal(r[1].to_s, "(0,101;2,103)/(10,111;12,113) props={}") assert_equal(r[100].inspect, "nil") assert_equal(r.bbox.to_s, "(0,1;212,113)") @@ -622,6 +622,7 @@ class DBEdgePairs_TestClass < TestBase r = RBA::EdgePairs::new([ RBA::EdgePairWithProperties::new(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 100), RBA::Edge::new(200, 300, 200, 500)), { 1 => "one" }) ]) assert_equal(r.to_s, "(0,0;100,100)/(200,300;200,500){1=>one}") + assert_equal(r[0].to_s, "(0,0;100,100)/(200,300;200,500) props={1=>one}") r = RBA::EdgePairs::new([]) assert_equal(r.to_s, "") diff --git a/testdata/ruby/dbEdgesTest.rb b/testdata/ruby/dbEdgesTest.rb index 086a0eb9c..7a8047b23 100644 --- a/testdata/ruby/dbEdgesTest.rb +++ b/testdata/ruby/dbEdgesTest.rb @@ -235,7 +235,7 @@ class DBEdges_TestClass < TestBase assert_equal(r.is_empty?, false) assert_equal(r.count, 12) assert_equal(r.hier_count, 12) - assert_equal(r[1].to_s, "(-10,20;10,20)") + assert_equal(r[1].to_s, "(-10,20;10,20) props={}") assert_equal(r[100].to_s, "") assert_equal(r.bbox.to_s, "(-10,-20;210,120)") assert_equal(r.is_merged?, false) @@ -252,11 +252,11 @@ class DBEdges_TestClass < TestBase r.flatten assert_equal(r.has_valid_edges?, true) - assert_equal(r[1].to_s, "(-10,80;10,120)") + assert_equal(r[1].to_s, "(-10,80;10,120) props={}") assert_equal(r[100].to_s, "") assert_equal(r.bbox.to_s, "(-10,-20;210,120)") assert_equal(r.is_merged?, false) - + r = RBA::Edges::new(ly.begin_shapes(c1.cell_index, l1), RBA::ICplxTrans::new(10, 20), true) assert_equal(r.to_s(30), "(0,0;0,40);(0,40;20,40);(20,40;20,0);(20,0;0,0);(0,100;0,140);(0,140;20,140);(20,140;20,100);(20,100;0,100);(200,100;200,140);(200,140;220,140);(220,140;220,100);(220,100;200,100)") assert_equal(r.is_empty?, false) @@ -970,6 +970,7 @@ class DBEdges_TestClass < TestBase r = RBA::Edges::new([ RBA::EdgeWithProperties::new(RBA::Edge::new(0, 0, 100, 100), { 1 => "one" }) ]) assert_equal(r.to_s, "(0,0;100,100){1=>one}") + assert_equal(r[0].to_s, "(0,0;100,100) props={1=>one}") r = RBA::Edges::new([]) assert_equal(r.to_s, "")