distance_brute_force.hpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2014, 2018 Oracle and/or its affiliates.
  4. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  5. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  6. // Licensed under the Boost Software License version 1.0.
  7. // http://www.boost.org/users/license.html
  8. #ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
  9. #define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
  10. #include <iterator>
  11. #include <boost/mpl/assert.hpp>
  12. #include <boost/mpl/or.hpp>
  13. #include <boost/range.hpp>
  14. #include <boost/geometry/core/reverse_dispatch.hpp>
  15. #include <boost/geometry/core/tag.hpp>
  16. #include <boost/geometry/core/tag_cast.hpp>
  17. #include <boost/geometry/core/tags.hpp>
  18. #include <boost/geometry/iterators/segment_iterator.hpp>
  19. #include <boost/geometry/algorithms/distance.hpp>
  20. #include <boost/geometry/algorithms/intersects.hpp>
  21. #include <boost/geometry/algorithms/not_implemented.hpp>
  22. namespace boost { namespace geometry
  23. {
  24. namespace unit_test
  25. {
  26. namespace detail { namespace distance_brute_force
  27. {
  28. struct distance_from_bg
  29. {
  30. template <typename G>
  31. struct use_distance_from_bg
  32. {
  33. typedef typename boost::mpl::or_
  34. <
  35. boost::is_same<typename tag<G>::type, point_tag>,
  36. typename boost::mpl::or_
  37. <
  38. boost::is_same<typename tag<G>::type, segment_tag>,
  39. boost::is_same<typename tag<G>::type, box_tag>
  40. >::type
  41. >::type type;
  42. };
  43. template <typename Geometry1, typename Geometry2, typename Strategy>
  44. static inline
  45. typename distance_result<Geometry1, Geometry2, Strategy>::type
  46. apply(Geometry1 const& geometry1,
  47. Geometry2 const& geometry2,
  48. Strategy const& strategy)
  49. {
  50. BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
  51. BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
  52. return geometry::distance(geometry1, geometry2, strategy);
  53. }
  54. };
  55. template <typename Geometry1, typename Geometry2, typename Strategy>
  56. inline
  57. typename distance_result<Geometry1, Geometry2, Strategy>::type
  58. bg_distance(Geometry1 const& geometry1,
  59. Geometry2 const& geometry2,
  60. Strategy const& strategy)
  61. {
  62. return distance_from_bg::apply(geometry1, geometry2, strategy);
  63. }
  64. template <typename Policy>
  65. struct one_to_many
  66. {
  67. template <typename Geometry, typename Iterator, typename Strategy>
  68. static inline typename distance_result
  69. <
  70. Geometry,
  71. typename std::iterator_traits<Iterator>::value_type,
  72. Strategy
  73. >::type
  74. apply(Geometry const& geometry, Iterator begin, Iterator end,
  75. Strategy const& strategy)
  76. {
  77. typedef typename distance_result
  78. <
  79. Geometry,
  80. typename std::iterator_traits<Iterator>::value_type,
  81. Strategy
  82. >::type distance_type;
  83. bool first = true;
  84. distance_type d_min(0);
  85. for (Iterator it = begin; it != end; ++it, first = false)
  86. {
  87. distance_type d = Policy::apply(geometry, *it, strategy);
  88. if ( first || d < d_min )
  89. {
  90. d_min = d;
  91. }
  92. }
  93. return d_min;
  94. }
  95. };
  96. }} // namespace detail::distance_brute_force
  97. namespace dispatch
  98. {
  99. template
  100. <
  101. typename Geometry1,
  102. typename Geometry2,
  103. typename Strategy,
  104. typename Tag1 = typename tag_cast
  105. <
  106. typename tag<Geometry1>::type,
  107. segment_tag,
  108. linear_tag
  109. >::type,
  110. typename Tag2 = typename tag_cast
  111. <
  112. typename tag<Geometry2>::type,
  113. segment_tag,
  114. linear_tag
  115. >::type,
  116. bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
  117. >
  118. struct distance_brute_force
  119. : not_implemented<Geometry1, Geometry2>
  120. {};
  121. template
  122. <
  123. typename Geometry1,
  124. typename Geometry2,
  125. typename Strategy,
  126. typename Tag1,
  127. typename Tag2
  128. >
  129. struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
  130. {
  131. static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
  132. apply(Geometry1 const& geometry1,
  133. Geometry2 const& geometry2,
  134. Strategy const& strategy)
  135. {
  136. return distance_brute_force
  137. <
  138. Geometry2, Geometry1, Strategy
  139. >::apply(geometry2, geometry1, strategy);
  140. }
  141. };
  142. //===================================================================
  143. template
  144. <
  145. typename Point1,
  146. typename Point2,
  147. typename Strategy
  148. >
  149. struct distance_brute_force
  150. <
  151. Point1, Point2, Strategy,
  152. point_tag, point_tag, false
  153. > : detail::distance_brute_force::distance_from_bg
  154. {};
  155. template
  156. <
  157. typename Point,
  158. typename Segment,
  159. typename Strategy
  160. >
  161. struct distance_brute_force
  162. <
  163. Point, Segment, Strategy,
  164. point_tag, segment_tag, false
  165. > : detail::distance_brute_force::distance_from_bg
  166. {};
  167. template
  168. <
  169. typename Point,
  170. typename Linear,
  171. typename Strategy
  172. >
  173. struct distance_brute_force
  174. <
  175. Point, Linear, Strategy,
  176. point_tag, linear_tag, false
  177. >
  178. {
  179. typedef typename distance_result
  180. <
  181. Point, Linear, Strategy
  182. >::type distance_type;
  183. static inline distance_type apply(Point const& point,
  184. Linear const& linear,
  185. Strategy const& strategy)
  186. {
  187. return detail::distance_brute_force::one_to_many
  188. <
  189. detail::distance_brute_force::distance_from_bg
  190. >::apply(point,
  191. geometry::segments_begin(linear),
  192. geometry::segments_end(linear),
  193. strategy);
  194. }
  195. };
  196. template
  197. <
  198. typename Point,
  199. typename Ring,
  200. typename Strategy
  201. >
  202. struct distance_brute_force
  203. <
  204. Point, Ring, Strategy,
  205. point_tag, ring_tag, false
  206. >
  207. {
  208. typedef typename distance_result
  209. <
  210. Point, Ring, Strategy
  211. >::type distance_type;
  212. static inline distance_type apply(Point const& point,
  213. Ring const& ring,
  214. Strategy const& strategy)
  215. {
  216. if (geometry::covered_by(point, ring))
  217. {
  218. return 0;
  219. }
  220. return detail::distance_brute_force::one_to_many
  221. <
  222. distance_brute_force
  223. <
  224. Point,
  225. typename std::iterator_traits
  226. <
  227. segment_iterator<Ring const>
  228. >::value_type,
  229. Strategy
  230. >
  231. >::apply(point,
  232. geometry::segments_begin(ring),
  233. geometry::segments_end(ring),
  234. strategy);
  235. }
  236. };
  237. //TODO do it more brute force (also in all polygon-geometry cases)
  238. template
  239. <
  240. typename Point,
  241. typename Polygon,
  242. typename Strategy
  243. >
  244. struct distance_brute_force
  245. <
  246. Point, Polygon, Strategy,
  247. point_tag, polygon_tag, false
  248. >
  249. {
  250. typedef typename distance_result
  251. <
  252. Point, Polygon, Strategy
  253. >::type distance_type;
  254. static inline distance_type apply(Point const& point,
  255. Polygon const& polygon,
  256. Strategy const& strategy)
  257. {
  258. return geometry::distance(point, polygon, strategy);
  259. }
  260. };
  261. template
  262. <
  263. typename Point,
  264. typename Box,
  265. typename Strategy
  266. >
  267. struct distance_brute_force
  268. <
  269. Point, Box, Strategy,
  270. point_tag, box_tag, false
  271. > : detail::distance_brute_force::distance_from_bg
  272. {};
  273. template
  274. <
  275. typename Point,
  276. typename MultiPoint,
  277. typename Strategy
  278. >
  279. struct distance_brute_force
  280. <
  281. Point, MultiPoint, Strategy,
  282. point_tag, multi_point_tag, false
  283. >
  284. {
  285. typedef typename distance_result
  286. <
  287. Point, MultiPoint, Strategy
  288. >::type distance_type;
  289. static inline distance_type apply(Point const& p,
  290. MultiPoint const& mp,
  291. Strategy const& strategy)
  292. {
  293. return detail::distance_brute_force::one_to_many
  294. <
  295. detail::distance_brute_force::distance_from_bg
  296. >::apply(p, boost::begin(mp), boost::end(mp), strategy);
  297. }
  298. };
  299. template
  300. <
  301. typename Point,
  302. typename MultiPolygon,
  303. typename Strategy
  304. >
  305. struct distance_brute_force
  306. <
  307. Point, MultiPolygon, Strategy,
  308. point_tag, multi_polygon_tag, false
  309. >
  310. {
  311. typedef typename distance_result
  312. <
  313. Point, MultiPolygon, Strategy
  314. >::type distance_type;
  315. static inline distance_type apply(Point const& p,
  316. MultiPolygon const& mp,
  317. Strategy const& strategy)
  318. {
  319. return detail::distance_brute_force::one_to_many
  320. <
  321. distance_brute_force
  322. <
  323. Point,
  324. typename boost::range_value<MultiPolygon>::type,
  325. Strategy
  326. >
  327. >::apply(p, boost::begin(mp), boost::end(mp), strategy);
  328. }
  329. };
  330. //=======================================================================
  331. template
  332. <
  333. typename Linear,
  334. typename Segment,
  335. typename Strategy
  336. >
  337. struct distance_brute_force
  338. <
  339. Linear, Segment, Strategy,
  340. linear_tag, segment_tag, false
  341. >
  342. {
  343. typedef typename distance_result
  344. <
  345. Linear, Segment, Strategy
  346. >::type distance_type;
  347. static inline distance_type apply(Linear const& linear,
  348. Segment const& segment,
  349. Strategy const& strategy)
  350. {
  351. return detail::distance_brute_force::one_to_many
  352. <
  353. detail::distance_brute_force::distance_from_bg
  354. >::apply(segment,
  355. geometry::segments_begin(linear),
  356. geometry::segments_end(linear),
  357. strategy);
  358. }
  359. };
  360. template
  361. <
  362. typename Linear1,
  363. typename Linear2,
  364. typename Strategy
  365. >
  366. struct distance_brute_force
  367. <
  368. Linear1, Linear2, Strategy,
  369. linear_tag, linear_tag, false
  370. >
  371. {
  372. typedef typename distance_result
  373. <
  374. Linear1, Linear2, Strategy
  375. >::type distance_type;
  376. static inline distance_type apply(Linear1 const& linear1,
  377. Linear2 const& linear2,
  378. Strategy const& strategy)
  379. {
  380. return detail::distance_brute_force::one_to_many
  381. <
  382. distance_brute_force
  383. <
  384. Linear1,
  385. typename std::iterator_traits
  386. <
  387. segment_iterator<Linear2 const>
  388. >::value_type,
  389. Strategy
  390. >
  391. >::apply(linear1,
  392. geometry::segments_begin(linear2),
  393. geometry::segments_end(linear2),
  394. strategy);
  395. }
  396. };
  397. template
  398. <
  399. typename Linear,
  400. typename Ring,
  401. typename Strategy
  402. >
  403. struct distance_brute_force
  404. <
  405. Linear, Ring, Strategy,
  406. linear_tag, ring_tag, false
  407. >
  408. {
  409. typedef typename distance_result
  410. <
  411. Linear, Ring, Strategy
  412. >::type distance_type;
  413. static inline distance_type apply(Linear const& linear,
  414. Ring const& ring,
  415. Strategy const& strategy)
  416. {
  417. return detail::distance_brute_force::one_to_many
  418. <
  419. distance_brute_force
  420. <
  421. Linear,
  422. typename std::iterator_traits
  423. <
  424. segment_iterator<Ring const>
  425. >::value_type,
  426. Strategy
  427. >
  428. >::apply(linear,
  429. geometry::segments_begin(ring),
  430. geometry::segments_end(ring),
  431. strategy);
  432. }
  433. };
  434. template
  435. <
  436. typename Linear,
  437. typename Polygon,
  438. typename Strategy
  439. >
  440. struct distance_brute_force
  441. <
  442. Linear, Polygon, Strategy,
  443. linear_tag, polygon_tag, false
  444. >
  445. {
  446. typedef typename distance_result
  447. <
  448. Linear, Polygon, Strategy
  449. >::type distance_type;
  450. static inline distance_type apply(Linear const& linear,
  451. Polygon const& polygon,
  452. Strategy const& strategy)
  453. {
  454. return detail::distance_brute_force::one_to_many
  455. <
  456. distance_brute_force
  457. <
  458. Polygon,
  459. typename std::iterator_traits
  460. <
  461. segment_iterator<Linear const>
  462. >::value_type,
  463. Strategy
  464. >
  465. >::apply(polygon,
  466. geometry::segments_begin(linear),
  467. geometry::segments_end(linear),
  468. strategy);
  469. }
  470. };
  471. template
  472. <
  473. typename Linear,
  474. typename Box,
  475. typename Strategy
  476. >
  477. struct distance_brute_force
  478. <
  479. Linear, Box, Strategy,
  480. linear_tag, box_tag, false
  481. >
  482. {
  483. typedef typename distance_result
  484. <
  485. Linear, Box, Strategy
  486. >::type distance_type;
  487. static inline distance_type apply(Linear const& linear,
  488. Box const& box,
  489. Strategy const& strategy)
  490. {
  491. return detail::distance_brute_force::one_to_many
  492. <
  493. detail::distance_brute_force::distance_from_bg
  494. >::apply(box,
  495. geometry::segments_begin(linear),
  496. geometry::segments_end(linear),
  497. strategy);
  498. }
  499. };
  500. template
  501. <
  502. typename Linear,
  503. typename MultiPoint,
  504. typename Strategy
  505. >
  506. struct distance_brute_force
  507. <
  508. Linear, MultiPoint, Strategy,
  509. linear_tag, multi_point_tag, false
  510. >
  511. {
  512. typedef typename distance_result
  513. <
  514. Linear, MultiPoint, Strategy
  515. >::type distance_type;
  516. static inline distance_type apply(Linear const& linear,
  517. MultiPoint const& mp,
  518. Strategy const& strategy)
  519. {
  520. return detail::distance_brute_force::one_to_many
  521. <
  522. distance_brute_force
  523. <
  524. Linear,
  525. typename boost::range_value<MultiPoint>::type,
  526. Strategy
  527. >
  528. >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
  529. }
  530. };
  531. template
  532. <
  533. typename Linear,
  534. typename MultiPolygon,
  535. typename Strategy
  536. >
  537. struct distance_brute_force
  538. <
  539. Linear, MultiPolygon, Strategy,
  540. linear_tag, multi_polygon_tag, false
  541. >
  542. {
  543. typedef typename distance_result
  544. <
  545. Linear, MultiPolygon, Strategy
  546. >::type distance_type;
  547. static inline distance_type apply(Linear const& linear,
  548. MultiPolygon const& mp,
  549. Strategy const& strategy)
  550. {
  551. return detail::distance_brute_force::one_to_many
  552. <
  553. distance_brute_force
  554. <
  555. Linear,
  556. typename boost::range_value<MultiPolygon>::type,
  557. Strategy
  558. >
  559. >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
  560. }
  561. };
  562. //=================================================================
  563. template
  564. <
  565. typename Polygon,
  566. typename Segment,
  567. typename Strategy
  568. >
  569. struct distance_brute_force
  570. <
  571. Polygon, Segment, Strategy,
  572. polygon_tag, segment_tag, false
  573. >
  574. {
  575. typedef typename distance_result
  576. <
  577. Polygon, Segment, Strategy
  578. >::type distance_type;
  579. static inline distance_type apply(Polygon const& polygon,
  580. Segment const& segment,
  581. Strategy const& strategy)
  582. {
  583. return geometry::distance(segment, polygon, strategy);
  584. }
  585. };
  586. template
  587. <
  588. typename Polygon,
  589. typename Linear,
  590. typename Strategy
  591. >
  592. struct distance_brute_force
  593. <
  594. Polygon, Linear, Strategy,
  595. polygon_tag, linear_tag, false
  596. >
  597. {
  598. typedef typename distance_result
  599. <
  600. Polygon, Linear, Strategy
  601. >::type distance_type;
  602. static inline distance_type apply(Polygon const& polygon,
  603. Linear const& linear,
  604. Strategy const& strategy)
  605. {
  606. return detail::distance_brute_force::one_to_many
  607. <
  608. distance_brute_force
  609. <
  610. Polygon,
  611. typename std::iterator_traits
  612. <
  613. segment_iterator<Linear const>
  614. >::value_type,
  615. Strategy
  616. >
  617. >::apply(polygon,
  618. geometry::segments_begin(linear),
  619. geometry::segments_end(linear),
  620. strategy);
  621. }
  622. };
  623. template
  624. <
  625. typename Polygon1,
  626. typename Polygon2,
  627. typename Strategy
  628. >
  629. struct distance_brute_force
  630. <
  631. Polygon1, Polygon2, Strategy,
  632. polygon_tag, polygon_tag, false
  633. >
  634. {
  635. typedef typename distance_result
  636. <
  637. Polygon1, Polygon2, Strategy
  638. >::type distance_type;
  639. static inline distance_type apply(Polygon1 const& polygon1,
  640. Polygon2 const& polygon2,
  641. Strategy const& strategy)
  642. {
  643. return geometry::distance(polygon1, polygon2, strategy);
  644. }
  645. };
  646. template
  647. <
  648. typename Polygon,
  649. typename MultiPoint,
  650. typename Strategy
  651. >
  652. struct distance_brute_force
  653. <
  654. Polygon, MultiPoint, Strategy,
  655. polygon_tag, multi_point_tag, false
  656. >
  657. {
  658. typedef typename distance_result
  659. <
  660. Polygon, MultiPoint, Strategy
  661. >::type distance_type;
  662. static inline distance_type apply(Polygon const& polygon,
  663. MultiPoint const& mp,
  664. Strategy const& strategy)
  665. {
  666. return detail::distance_brute_force::one_to_many
  667. <
  668. distance_brute_force
  669. <
  670. Polygon,
  671. typename boost::range_value<MultiPoint>::type,
  672. Strategy
  673. >
  674. >::apply(polygon, boost::begin(mp), boost::end(mp), strategy);
  675. }
  676. };
  677. template
  678. <
  679. typename Polygon,
  680. typename MultiPolygon,
  681. typename Strategy
  682. >
  683. struct distance_brute_force
  684. <
  685. Polygon, MultiPolygon, Strategy,
  686. polygon_tag, multi_polygon_tag, false
  687. >
  688. {
  689. typedef typename distance_result
  690. <
  691. Polygon, MultiPolygon, Strategy
  692. >::type distance_type;
  693. static inline distance_type apply(Polygon const& poly,
  694. MultiPolygon const& mp,
  695. Strategy const& strategy)
  696. {
  697. return detail::distance_brute_force::one_to_many
  698. <
  699. distance_brute_force
  700. <
  701. Polygon,
  702. typename boost::range_value<MultiPolygon>::type,
  703. Strategy
  704. >
  705. >::apply(poly, boost::begin(mp), boost::end(mp), strategy);
  706. }
  707. };
  708. template
  709. <
  710. typename Polygon,
  711. typename Ring,
  712. typename Strategy
  713. >
  714. struct distance_brute_force
  715. <
  716. Polygon, Ring, Strategy,
  717. polygon_tag, ring_tag, false
  718. >
  719. {
  720. typedef typename distance_result
  721. <
  722. Polygon, Ring, Strategy
  723. >::type distance_type;
  724. static inline distance_type apply(Polygon const& polygon,
  725. Ring const& ring,
  726. Strategy const& strategy)
  727. {
  728. return geometry::distance(ring, polygon, strategy);
  729. }
  730. };
  731. template
  732. <
  733. typename Polygon,
  734. typename Box,
  735. typename Strategy
  736. >
  737. struct distance_brute_force
  738. <
  739. Polygon, Box, Strategy,
  740. polygon_tag, box_tag, false
  741. >
  742. {
  743. typedef typename distance_result
  744. <
  745. Polygon, Box, Strategy
  746. >::type distance_type;
  747. static inline distance_type apply(Polygon const& polygon,
  748. Box const& box,
  749. Strategy const& strategy)
  750. {
  751. return geometry::distance(box, polygon, strategy);
  752. }
  753. };
  754. //========================================================================
  755. template
  756. <
  757. typename MultiPoint1,
  758. typename MultiPoint2,
  759. typename Strategy
  760. >
  761. struct distance_brute_force
  762. <
  763. MultiPoint1, MultiPoint2, Strategy,
  764. multi_point_tag, multi_point_tag, false
  765. >
  766. {
  767. typedef typename distance_result
  768. <
  769. MultiPoint1, MultiPoint2, Strategy
  770. >::type distance_type;
  771. static inline distance_type apply(MultiPoint1 const& mp1,
  772. MultiPoint2 const& mp2,
  773. Strategy const& strategy)
  774. {
  775. return detail::distance_brute_force::one_to_many
  776. <
  777. distance_brute_force
  778. <
  779. MultiPoint1,
  780. typename boost::range_value<MultiPoint2>::type,
  781. Strategy
  782. >
  783. >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
  784. }
  785. };
  786. template
  787. <
  788. typename MultiPoint,
  789. typename Linear,
  790. typename Strategy
  791. >
  792. struct distance_brute_force
  793. <
  794. MultiPoint, Linear, Strategy,
  795. multi_point_tag, linear_tag, false
  796. >
  797. {
  798. typedef typename distance_result
  799. <
  800. MultiPoint, Linear, Strategy
  801. >::type distance_type;
  802. static inline distance_type apply(MultiPoint const& mp,
  803. Linear const& l,
  804. Strategy const& strategy)
  805. {
  806. return detail::distance_brute_force::one_to_many
  807. <
  808. distance_brute_force
  809. <
  810. MultiPoint,
  811. typename boost::range_value<Linear>::type,
  812. Strategy
  813. >
  814. >::apply(mp, boost::begin(l), boost::end(l), strategy);
  815. }
  816. };
  817. template
  818. <
  819. typename MultiPoint,
  820. typename MultiPolygon,
  821. typename Strategy
  822. >
  823. struct distance_brute_force
  824. <
  825. MultiPoint, MultiPolygon, Strategy,
  826. multi_point_tag, multi_polygon_tag, false
  827. >
  828. {
  829. typedef typename distance_result
  830. <
  831. MultiPoint, MultiPolygon, Strategy
  832. >::type distance_type;
  833. static inline distance_type apply(MultiPoint const& mp,
  834. MultiPolygon const& mpl,
  835. Strategy const& strategy)
  836. {
  837. return detail::distance_brute_force::one_to_many
  838. <
  839. distance_brute_force
  840. <
  841. MultiPoint,
  842. typename boost::range_value<MultiPolygon>::type,
  843. Strategy
  844. >
  845. >::apply(mp, boost::begin(mpl), boost::end(mpl), strategy);
  846. }
  847. };
  848. template
  849. <
  850. typename MultiPoint,
  851. typename Segment,
  852. typename Strategy
  853. >
  854. struct distance_brute_force
  855. <
  856. MultiPoint, Segment, Strategy,
  857. multi_point_tag, segment_tag, false
  858. >
  859. {
  860. typedef typename distance_result
  861. <
  862. MultiPoint, Segment, Strategy
  863. >::type distance_type;
  864. static inline distance_type apply(MultiPoint const& mp,
  865. Segment const& segment,
  866. Strategy const& strategy)
  867. {
  868. return detail::distance_brute_force::one_to_many
  869. <
  870. detail::distance_brute_force::distance_from_bg
  871. >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
  872. }
  873. };
  874. template
  875. <
  876. typename MultiPoint,
  877. typename Ring,
  878. typename Strategy
  879. >
  880. struct distance_brute_force
  881. <
  882. MultiPoint, Ring, Strategy,
  883. multi_point_tag, ring_tag, false
  884. >
  885. {
  886. typedef typename distance_result
  887. <
  888. MultiPoint, Ring, Strategy
  889. >::type distance_type;
  890. static inline distance_type apply(MultiPoint const& mp,
  891. Ring const& ring,
  892. Strategy const& strategy)
  893. {
  894. return detail::distance_brute_force::one_to_many
  895. <
  896. distance_brute_force
  897. <
  898. MultiPoint,
  899. typename std::iterator_traits
  900. <
  901. segment_iterator<Ring const>
  902. >::value_type,
  903. Strategy
  904. >
  905. >::apply(mp,
  906. geometry::segments_begin(ring),
  907. geometry::segments_end(ring),
  908. strategy);
  909. }
  910. };
  911. template
  912. <
  913. typename MultiPoint,
  914. typename Box,
  915. typename Strategy
  916. >
  917. struct distance_brute_force
  918. <
  919. MultiPoint, Box, Strategy,
  920. multi_point_tag, box_tag, false
  921. >
  922. {
  923. typedef typename distance_result
  924. <
  925. MultiPoint, Box, Strategy
  926. >::type distance_type;
  927. static inline distance_type apply(MultiPoint const& mp,
  928. Box const& box,
  929. Strategy const& strategy)
  930. {
  931. return detail::distance_brute_force::one_to_many
  932. <
  933. distance_brute_force
  934. <
  935. Box,
  936. typename boost::range_value<MultiPoint>::type,
  937. Strategy
  938. >
  939. >::apply(box, boost::begin(mp), boost::end(mp), strategy);
  940. }
  941. };
  942. //=====================================================================
  943. template
  944. <
  945. typename MultiPolygon1,
  946. typename MultiPolygon2,
  947. typename Strategy
  948. >
  949. struct distance_brute_force
  950. <
  951. MultiPolygon1, MultiPolygon2, Strategy,
  952. multi_polygon_tag, multi_polygon_tag, false
  953. >
  954. {
  955. typedef typename distance_result
  956. <
  957. MultiPolygon1, MultiPolygon2, Strategy
  958. >::type distance_type;
  959. static inline distance_type apply(MultiPolygon1 const& mp1,
  960. MultiPolygon2 const& mp2,
  961. Strategy const& strategy)
  962. {
  963. return detail::distance_brute_force::one_to_many
  964. <
  965. distance_brute_force
  966. <
  967. MultiPolygon1,
  968. typename boost::range_value<MultiPolygon2>::type,
  969. Strategy
  970. >
  971. >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
  972. }
  973. };
  974. template
  975. <
  976. typename MultiPolygon,
  977. typename Segment,
  978. typename Strategy
  979. >
  980. struct distance_brute_force
  981. <
  982. MultiPolygon, Segment, Strategy,
  983. multi_polygon_tag, segment_tag, false
  984. >
  985. {
  986. typedef typename distance_result
  987. <
  988. MultiPolygon, Segment, Strategy
  989. >::type distance_type;
  990. static inline distance_type apply(MultiPolygon const& mp,
  991. Segment const& segment,
  992. Strategy const& strategy)
  993. {
  994. return detail::distance_brute_force::one_to_many
  995. <
  996. distance_brute_force
  997. <
  998. Segment,
  999. typename boost::range_value<MultiPolygon>::type,
  1000. Strategy
  1001. >
  1002. >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
  1003. }
  1004. };
  1005. template
  1006. <
  1007. typename MultiPolygon,
  1008. typename Ring,
  1009. typename Strategy
  1010. >
  1011. struct distance_brute_force
  1012. <
  1013. MultiPolygon, Ring, Strategy,
  1014. multi_polygon_tag, ring_tag, false
  1015. >
  1016. {
  1017. typedef typename distance_result
  1018. <
  1019. MultiPolygon, Ring, Strategy
  1020. >::type distance_type;
  1021. static inline distance_type apply(MultiPolygon const& mp,
  1022. Ring const& ring,
  1023. Strategy const& strategy)
  1024. {
  1025. return detail::distance_brute_force::one_to_many
  1026. <
  1027. distance_brute_force
  1028. <
  1029. Ring,
  1030. typename boost::range_value<MultiPolygon>::type,
  1031. Strategy
  1032. >
  1033. >::apply(ring, boost::begin(mp), boost::end(mp), strategy);
  1034. }
  1035. };
  1036. template
  1037. <
  1038. typename MultiPolygon,
  1039. typename Box,
  1040. typename Strategy
  1041. >
  1042. struct distance_brute_force
  1043. <
  1044. MultiPolygon, Box, Strategy,
  1045. multi_polygon_tag, box_tag, false
  1046. >
  1047. {
  1048. typedef typename distance_result
  1049. <
  1050. MultiPolygon, Box, Strategy
  1051. >::type distance_type;
  1052. static inline distance_type apply(MultiPolygon const& mp,
  1053. Box const& box,
  1054. Strategy const& strategy)
  1055. {
  1056. return detail::distance_brute_force::one_to_many
  1057. <
  1058. distance_brute_force
  1059. <
  1060. Box,
  1061. typename boost::range_value<MultiPolygon>::type,
  1062. Strategy
  1063. >
  1064. >::apply(box, boost::begin(mp), boost::end(mp), strategy);
  1065. }
  1066. };
  1067. //========================================================================
  1068. template
  1069. <
  1070. typename Ring,
  1071. typename Box,
  1072. typename Strategy
  1073. >
  1074. struct distance_brute_force
  1075. <
  1076. Ring, Box, Strategy,
  1077. ring_tag, box_tag, false
  1078. >
  1079. {
  1080. typedef typename distance_result
  1081. <
  1082. Ring, Box, Strategy
  1083. >::type distance_type;
  1084. static inline distance_type apply(Ring const& ring,
  1085. Box const& box,
  1086. Strategy const& strategy)
  1087. {
  1088. return detail::distance_brute_force::one_to_many
  1089. <
  1090. distance_brute_force
  1091. <
  1092. Box,
  1093. typename std::iterator_traits
  1094. <
  1095. segment_iterator<Ring const>
  1096. >::value_type,
  1097. Strategy
  1098. >
  1099. >::apply(box,
  1100. geometry::segments_begin(ring),
  1101. geometry::segments_end(ring),
  1102. strategy);
  1103. }
  1104. };
  1105. template
  1106. <
  1107. typename Ring1,
  1108. typename Ring2,
  1109. typename Strategy
  1110. >
  1111. struct distance_brute_force
  1112. <
  1113. Ring1, Ring2, Strategy,
  1114. ring_tag, ring_tag, false
  1115. >
  1116. {
  1117. typedef typename distance_result
  1118. <
  1119. Ring1, Ring2, Strategy
  1120. >::type distance_type;
  1121. static inline distance_type apply(Ring1 const& ring1,
  1122. Ring2 const& ring2,
  1123. Strategy const& strategy)
  1124. {
  1125. return detail::distance_brute_force::one_to_many
  1126. <
  1127. distance_brute_force
  1128. <
  1129. Ring1,
  1130. typename std::iterator_traits
  1131. <
  1132. segment_iterator<Ring2 const>
  1133. >::value_type,
  1134. Strategy
  1135. >
  1136. >::apply(ring1,
  1137. geometry::segments_begin(ring2),
  1138. geometry::segments_end(ring2),
  1139. strategy);
  1140. }
  1141. };
  1142. //========================================================================
  1143. template
  1144. <
  1145. typename Segment1,
  1146. typename Segment2,
  1147. typename Strategy
  1148. >
  1149. struct distance_brute_force
  1150. <
  1151. Segment1, Segment2, Strategy,
  1152. segment_tag, segment_tag, false
  1153. > : detail::distance_brute_force::distance_from_bg
  1154. {};
  1155. template
  1156. <
  1157. typename Segment,
  1158. typename Ring,
  1159. typename Strategy
  1160. >
  1161. struct distance_brute_force
  1162. <
  1163. Segment, Ring, Strategy,
  1164. segment_tag, ring_tag, false
  1165. >
  1166. {
  1167. typedef typename distance_result
  1168. <
  1169. Segment, Ring, Strategy
  1170. >::type distance_type;
  1171. static inline distance_type apply(Segment const& segment,
  1172. Ring const& ring,
  1173. Strategy const& strategy)
  1174. {
  1175. return detail::distance_brute_force::one_to_many
  1176. <
  1177. distance_brute_force
  1178. <
  1179. Segment,
  1180. typename std::iterator_traits
  1181. <
  1182. segment_iterator<Ring const>
  1183. >::value_type,
  1184. Strategy
  1185. >
  1186. >::apply(segment,
  1187. geometry::segments_begin(ring),
  1188. geometry::segments_end(ring),
  1189. strategy);
  1190. }
  1191. };
  1192. template
  1193. <
  1194. typename Segment,
  1195. typename Box,
  1196. typename Strategy
  1197. >
  1198. struct distance_brute_force
  1199. <
  1200. Segment, Box, Strategy,
  1201. segment_tag, box_tag, false
  1202. > : detail::distance_brute_force::distance_from_bg
  1203. {};
  1204. //====================================================================
  1205. template
  1206. <
  1207. typename Box1,
  1208. typename Box2,
  1209. typename Strategy
  1210. >
  1211. struct distance_brute_force
  1212. <
  1213. Box1, Box2, Strategy,
  1214. box_tag, box_tag, false
  1215. > : detail::distance_brute_force::distance_from_bg
  1216. {};
  1217. } // namespace dispatch
  1218. template <typename Geometry1, typename Geometry2, typename Strategy>
  1219. inline typename distance_result<Geometry1, Geometry2, Strategy>::type
  1220. distance_brute_force(Geometry1 const& geometry1,
  1221. Geometry2 const& geometry2,
  1222. Strategy const& strategy)
  1223. {
  1224. return dispatch::distance_brute_force
  1225. <
  1226. Geometry1, Geometry2, Strategy
  1227. >::apply(geometry1, geometry2, strategy);
  1228. }
  1229. } // namespace unit_test
  1230. }} // namespace boost::geometry
  1231. #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP