Boost logo

Geometry :

Subject: Re: [geometry] Generic intersects function
From: Kor de Jong (kor_at_[hidden])
Date: 2015-02-17 03:10:59


Dear Ido,

On 16/02/15 00:18, Ido Shlomo wrote:
> I'm trying to write a generic intersects
> <http://www.boost.org/doc/libs/1_57_0/libs/geometry/doc/html/geometry/reference/algorithms/intersects/intersects_2_two_geometries.html>/read_wkt
> <http://www.boost.org/doc/libs/1_57_0/libs/geometry/doc/html/geometry/reference/io/wkt/read_wkt.html> function
> which reads 2 shapes (can be point/polygon/linestring/box) and returns
> whether the shapes intersect.
> I tried running the following code but found out Geometry is not a type
> but a typename for template:
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> Geometry g;
> Geometry y;
>
> boost::geometry::read_wkt("POLYGON((35 25, 15 25, 15 35, 35 35, 35
> 25))", g);
> boost::geometry::read_wkt("POLYGON((45 30, 25 30, 25 50, 45 50, 45
> 30))", y);
>
> std::cout << intersects(g,y) << std::endl;
>
> return 0;
> }

According to the docs, Geometry is 'Any type fulfilling a Geometry
Concept'. You need to look up the Geometry Concept and use a type that
models it. The example on the read_wkt page shows various example types
you can use. You can also use your own types, as long as they model the
Geometry concept.

> I can see 2 problems:
>
> 1. read_wkt has to know which type it is going to read - polygon / box
> / point / etc..
> 2. Same for intersects
>
>
> Do you have a suggestion how i could decide the type in runtime?
> (let's say i'm reading database records which i don't know for sure if
> they will be point / polygon)

As you probably know, templates can't be instantiated at runtime based
on some criterium. The compiler instantiates templates, at compile time.
But you can do things like this:

GeometryTypeId geometry_type_id = probe_database_for_geometry_type()

switch(geometry_type_id) {
     case polygon: {
         do_useful_stuff<Polygon>();
         break;
     }
     case point: {
         do_useful_stuff<Point>();
         break;
     }
     ...
}

do_useful_stuff could read the geometries from the database and
calculate some result.

> I don't want to write a code specific to handling each of the cases even
> if it won't be long..
> Does anyone think of a generic solution?

You don't know the geometry type in advance, so you can't create a fully
templated solution. Some knowledge you need has to be gathered at
runtime (reading the geometry type id from the database). Once you have
that, you can call a template instantiated by the corresponding geometry
type. So, it seems to me you need something like the switch statement
above, where for each case you can call code that is templated on the
Geometry type.
Switches like this repeat code per case, and I sometimes use
preprocessor macros to refactor the common code into macros
parameterized by case id. Both are not ideal.

Kor


Geometry list run by mateusz at loskot.net