1500 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			1500 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C++
		
	
	
/* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or modify
 | 
						|
   it under the terms of the GNU General Public License, version 2.0,
 | 
						|
   as published by the Free Software Foundation.
 | 
						|
 | 
						|
   This program is also distributed with certain software (including
 | 
						|
   but not limited to OpenSSL) that is licensed under separate terms,
 | 
						|
   as designated in a particular file or component or in included license
 | 
						|
   documentation.  The authors of MySQL hereby grant you an additional
 | 
						|
   permission to link the program and your derivative works with the
 | 
						|
   separately licensed software that they have included with MySQL.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
   GNU General Public License, version 2.0, for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software
 | 
						|
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 | 
						|
 | 
						|
#include "sql/item_geofunc_relchecks_bgwrap.h"
 | 
						|
 | 
						|
#include <algorithm>
 | 
						|
#include <boost/concept/usage.hpp>
 | 
						|
#include <boost/geometry/algorithms/equals.hpp>
 | 
						|
#include <boost/geometry/algorithms/intersects.hpp>
 | 
						|
#include <boost/geometry/algorithms/touches.hpp>
 | 
						|
#include <boost/geometry/algorithms/within.hpp>
 | 
						|
#include <boost/geometry/geometries/box.hpp>
 | 
						|
#include <boost/geometry/index/rtree.hpp>
 | 
						|
#include <boost/geometry/strategies/strategies.hpp>
 | 
						|
#include <utility>
 | 
						|
 | 
						|
#include "my_dbug.h"
 | 
						|
#include "sql/item_geofunc_internal.h"
 | 
						|
#include "sql/spatial.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'point WITHIN xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a point.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::point_within_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                               bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, within, Point, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, within, Point, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point)
 | 
						|
    BGCALL(result, within, Point, g1, Point, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipoint)
 | 
						|
    BGCALL(result, within, Point, g1, Multipoint, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, within, Point, g1, Linestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, within, Point, g1, Multilinestring, g2, pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint WITHIN xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_within_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                    bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
  const void *data_ptr = NULL;
 | 
						|
 | 
						|
  Multipoint mpts(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                  g1->get_srid());
 | 
						|
  if (gt2 == Geometry::wkb_polygon) {
 | 
						|
    data_ptr = g2->normalize_ring_order();
 | 
						|
    if (data_ptr == NULL) {
 | 
						|
      my_error(ER_GIS_INVALID_DATA, MYF(0), "st_within");
 | 
						|
      *pnull_value = true;
 | 
						|
      return result;
 | 
						|
    }
 | 
						|
 | 
						|
    Polygon plg(data_ptr, g2->get_data_size(), g2->get_flags(), g2->get_srid());
 | 
						|
 | 
						|
    result = multipoint_within_geometry_internal(mpts, plg);
 | 
						|
  } else if (gt2 == Geometry::wkb_multipolygon) {
 | 
						|
    data_ptr = g2->normalize_ring_order();
 | 
						|
    if (data_ptr == NULL) {
 | 
						|
      *pnull_value = true;
 | 
						|
      my_error(ER_GIS_INVALID_DATA, MYF(0), "st_within");
 | 
						|
      return result;
 | 
						|
    }
 | 
						|
 | 
						|
    Multipolygon mplg(data_ptr, g2->get_data_size(), g2->get_flags(),
 | 
						|
                      g2->get_srid());
 | 
						|
 | 
						|
    /*
 | 
						|
      One may want to build the rtree index on mpts when mpts has more
 | 
						|
      components than mplg, but then one would have to track the points that
 | 
						|
      are already known to be in one of mplg's polygons and avoid checking
 | 
						|
      again (which may fail and cause false alarm) for other polygon components.
 | 
						|
      Such maintenance brings extra cost and performance test prooves that
 | 
						|
      it's not desirable.
 | 
						|
      The containers tried for such maintenance including std::vector<bool>,
 | 
						|
      std::set<array_index>, mpts[i].set_props().
 | 
						|
 | 
						|
      Also, even if the mplg has only one polygon, i.e. the worst case for
 | 
						|
      building rtree index on mplg, the performance is still very very close to
 | 
						|
      the linear search done in multipoint_within_geometry_internal.
 | 
						|
 | 
						|
      So always build index on mplg as below.
 | 
						|
    */
 | 
						|
    result = multipoint_within_multipolygon(mpts, mplg);
 | 
						|
  } else if (gt2 == Geometry::wkb_point) {
 | 
						|
    /* There may be duplicate Points, thus use a set to make them unique*/
 | 
						|
    Point_set ptset1(mpts.begin(), mpts.end());
 | 
						|
    Point pt(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
             g2->get_srid());
 | 
						|
    result =
 | 
						|
        ((ptset1.size() == 1) && boost::geometry::equals(*ptset1.begin(), pt));
 | 
						|
  } else if (gt2 == Geometry::wkb_multipoint) {
 | 
						|
    /* There may be duplicate Points, thus use a set to make them unique*/
 | 
						|
    Point_set ptset1(mpts.begin(), mpts.end());
 | 
						|
    Multipoint mpts2(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                     g2->get_srid());
 | 
						|
    Point_set ptset2(mpts2.begin(), mpts2.end());
 | 
						|
    Point_vector respts;
 | 
						|
    typename Point_vector::iterator endpos;
 | 
						|
    respts.resize(std::max(ptset1.size(), ptset2.size()));
 | 
						|
    endpos = std::set_intersection(ptset1.begin(), ptset1.end(), ptset2.begin(),
 | 
						|
                                   ptset2.end(), respts.begin(), bgpt_lt());
 | 
						|
    result = (ptset1.size() == static_cast<size_t>(endpos - respts.begin()));
 | 
						|
  } else if (gt2 == Geometry::wkb_linestring) {
 | 
						|
    Linestring ls(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                  g2->get_srid());
 | 
						|
    result = multipoint_within_geometry_internal(mpts, ls);
 | 
						|
  } else if (gt2 == Geometry::wkb_multilinestring) {
 | 
						|
    Multilinestring mls(g2->get_data_ptr(), g2->get_data_size(),
 | 
						|
                        g2->get_flags(), g2->get_srid());
 | 
						|
    /*
 | 
						|
      Here we can't separate linestrings of a multilinstring MLS to do within
 | 
						|
      check one by one because if N (N > 1) linestrings share the same boundary
 | 
						|
      point P, P may or may not be a boundary point of MLS, depending on N%2,
 | 
						|
      if N is an even number P is an internal point of MLS, otherwise P is a
 | 
						|
      boundary point of MLS.
 | 
						|
    */
 | 
						|
    result = multipoint_within_geometry_internal(mpts, mls);
 | 
						|
  } else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
template <typename GeomType>
 | 
						|
int BG_wrap<Geom_types>::multipoint_within_geometry_internal(
 | 
						|
    const Multipoint &mpts, const GeomType &geom) {
 | 
						|
  bool has_inner = false;
 | 
						|
 | 
						|
  for (typename Multipoint::iterator i = mpts.begin(); i != mpts.end(); ++i) {
 | 
						|
    /*
 | 
						|
      Checking for intersects is faster than within, so if there is at least
 | 
						|
      one point within geom, only check that the rest points intersects geom.
 | 
						|
     */
 | 
						|
    if (!has_inner && (has_inner = boost::geometry::within(*i, geom))) continue;
 | 
						|
 | 
						|
    if (!boost::geometry::intersects(*i, geom)) return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return has_inner;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_within_multipolygon(
 | 
						|
    const Multipoint &mpts, const Multipolygon &mplgn) {
 | 
						|
  bool has_inner = false;
 | 
						|
 | 
						|
  Rtree_index rtree;
 | 
						|
  make_rtree_bggeom(mplgn, &rtree);
 | 
						|
  BG_box box;
 | 
						|
 | 
						|
  for (typename Multipoint::iterator i = mpts.begin(); i != mpts.end(); ++i) {
 | 
						|
    bool already_in = false;
 | 
						|
    // Search for polygons that may intersect *i point using the rtree index.
 | 
						|
    boost::geometry::envelope(*i, box);
 | 
						|
    Rtree_index::const_query_iterator j = rtree.qbegin(bgi::intersects(box));
 | 
						|
    if (j == rtree.qend()) return 0;
 | 
						|
    /*
 | 
						|
      All polygons that possibly intersect *i point are given by the
 | 
						|
      rtree iteration below.
 | 
						|
    */
 | 
						|
    for (; j != rtree.qend(); ++j) {
 | 
						|
      /*
 | 
						|
        Checking for intersects is faster than within, so if there is at least
 | 
						|
        one point within geom, only check that the rest points intersects geom.
 | 
						|
      */
 | 
						|
      const Polygon &plgn = mplgn[j->second];
 | 
						|
      /*
 | 
						|
        If we don't have a point in mpts that's within mplgn yet,
 | 
						|
        check whether *i is within plgn.
 | 
						|
        If *i is within plgn, it's already in the multipolygon, so no need
 | 
						|
        for more checks.
 | 
						|
      */
 | 
						|
      if (!has_inner && (has_inner = boost::geometry::within(*i, plgn))) {
 | 
						|
        already_in = true;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      /*
 | 
						|
        If we already have a point within mplgn, OR if *i is checked above to
 | 
						|
        be not within plgn, check whether *i intersects plgn.
 | 
						|
        *i has to intersect one of the components in this loop, otherwise *i
 | 
						|
        is out of mplgn.
 | 
						|
       */
 | 
						|
      if (boost::geometry::intersects(*i, plgn)) {
 | 
						|
        already_in = true;
 | 
						|
        /*
 | 
						|
          It's likely that *i is within another plgn, so only stop the
 | 
						|
          iteration if we already have a point that's within the multipolygon,
 | 
						|
          in order not to miss the polygon containing *i.
 | 
						|
        */
 | 
						|
        if (has_inner) break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
      The *i point isn't within or intersects any polygon of mplgn,
 | 
						|
      so mpts isn't within geom.
 | 
						|
    */
 | 
						|
    if (!already_in) return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  /*
 | 
						|
    All points in mpts at least intersects geom, so the result is determined
 | 
						|
    by whether there is at least one point in mpts that's within geom.
 | 
						|
  */
 | 
						|
  return has_inner;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::linestring_within_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                    bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, within, Linestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, within, Linestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point || gt2 == Geometry::wkb_multipoint)
 | 
						|
    return 0;
 | 
						|
  else if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, within, Linestring, g1, Linestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, within, Linestring, g1, Multilinestring, g2, pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_within_geometry(Geometry *g1,
 | 
						|
                                                         Geometry *g2,
 | 
						|
                                                         bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, within, Multilinestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, within, Multilinestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point || gt2 == Geometry::wkb_multipoint)
 | 
						|
    return 0;
 | 
						|
  else if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, within, Multilinestring, g1, Linestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, within, Multilinestring, g1, Multilinestring, g2,
 | 
						|
           pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::polygon_within_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                 bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, within, Polygon, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, within, Polygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point || gt2 == Geometry::wkb_multipoint ||
 | 
						|
           gt2 == Geometry::wkb_linestring ||
 | 
						|
           gt2 == Geometry::wkb_multilinestring)
 | 
						|
    return 0;
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipolygon_within_geometry(Geometry *g1,
 | 
						|
                                                      Geometry *g2,
 | 
						|
                                                      bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, within, Multipolygon, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, within, Multipolygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point || gt2 == Geometry::wkb_multipoint ||
 | 
						|
           gt2 == Geometry::wkb_linestring ||
 | 
						|
           gt2 == Geometry::wkb_multilinestring)
 | 
						|
    return 0;
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint EQUALS xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_equals_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                    bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      result = Ifsr::equals_check<Geom_types>(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint: {
 | 
						|
      Multipoint mpts1(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                       g1->get_srid());
 | 
						|
      Multipoint mpts2(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                       g2->get_srid());
 | 
						|
 | 
						|
      Point_set ptset1(mpts1.begin(), mpts1.end());
 | 
						|
      Point_set ptset2(mpts2.begin(), mpts2.end());
 | 
						|
      result =
 | 
						|
          (ptset1.size() == ptset2.size() &&
 | 
						|
           std::equal(ptset1.begin(), ptset1.end(), ptset2.begin(), bgpt_eq()));
 | 
						|
    } break;
 | 
						|
    default:
 | 
						|
      result = 0;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_disjoint_geometry(Geometry *g1,
 | 
						|
                                                      Geometry *g2,
 | 
						|
                                                      bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
  const void *data_ptr = NULL;
 | 
						|
 | 
						|
  Multipoint mpts1(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                   g1->get_srid());
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      result = point_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint: {
 | 
						|
      Multipoint mpts2(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                       g2->get_srid());
 | 
						|
      Point_set ptset1(mpts1.begin(), mpts1.end());
 | 
						|
      Point_set ptset2(mpts2.begin(), mpts2.end());
 | 
						|
      Point_vector respts;
 | 
						|
      typename Point_vector::iterator endpos;
 | 
						|
      size_t ptset1sz = ptset1.size(), ptset2sz = ptset2.size();
 | 
						|
 | 
						|
      respts.resize(ptset1sz > ptset2sz ? ptset1sz : ptset2sz);
 | 
						|
      endpos =
 | 
						|
          std::set_intersection(ptset1.begin(), ptset1.end(), ptset2.begin(),
 | 
						|
                                ptset2.end(), respts.begin(), bgpt_lt());
 | 
						|
      result = (endpos == respts.begin());
 | 
						|
    } break;
 | 
						|
    case Geometry::wkb_polygon: {
 | 
						|
      data_ptr = g2->normalize_ring_order();
 | 
						|
      if (data_ptr == NULL) {
 | 
						|
        *pnull_value = true;
 | 
						|
        my_error(ER_GIS_INVALID_DATA, MYF(0), "st_disjoint");
 | 
						|
        return result;
 | 
						|
      }
 | 
						|
 | 
						|
      Polygon plg(data_ptr, g2->get_data_size(), g2->get_flags(),
 | 
						|
                  g2->get_srid());
 | 
						|
      result = multipoint_disjoint_geometry_internal(mpts1, plg);
 | 
						|
    } break;
 | 
						|
    case Geometry::wkb_multipolygon: {
 | 
						|
      data_ptr = g2->normalize_ring_order();
 | 
						|
      if (data_ptr == NULL) {
 | 
						|
        *pnull_value = true;
 | 
						|
        my_error(ER_GIS_INVALID_DATA, MYF(0), "st_disjoint");
 | 
						|
        return result;
 | 
						|
      }
 | 
						|
 | 
						|
      Multipolygon mplg(data_ptr, g2->get_data_size(), g2->get_flags(),
 | 
						|
                        g2->get_srid());
 | 
						|
      result = multipoint_disjoint_multi_geometry(mpts1, mplg);
 | 
						|
    } break;
 | 
						|
    case Geometry::wkb_linestring: {
 | 
						|
      Linestring ls(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                    g2->get_srid());
 | 
						|
      result = multipoint_disjoint_geometry_internal(mpts1, ls);
 | 
						|
    } break;
 | 
						|
    case Geometry::wkb_multilinestring: {
 | 
						|
      Multilinestring mls(g2->get_data_ptr(), g2->get_data_size(),
 | 
						|
                          g2->get_flags(), g2->get_srid());
 | 
						|
      result = multipoint_disjoint_multi_geometry(mpts1, mls);
 | 
						|
    } break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
template <typename Geom_type>
 | 
						|
int BG_wrap<Geom_types>::multipoint_disjoint_geometry_internal(
 | 
						|
    const Multipoint &mpts, const Geom_type &geom) {
 | 
						|
  for (typename Multipoint::iterator i = mpts.begin(); i != mpts.end(); ++i) {
 | 
						|
    if (!boost::geometry::disjoint(*i, geom)) return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Geom_types>
 | 
						|
template <typename Geom_type>
 | 
						|
int BG_wrap<Geom_types>::multipoint_disjoint_multi_geometry(
 | 
						|
    const Multipoint &mpts, const Geom_type &geom) {
 | 
						|
  Rtree_index rtree;
 | 
						|
 | 
						|
  // Choose the one with more components to build rtree index on, to get more
 | 
						|
  // performance improvement.
 | 
						|
  if (mpts.size() > geom.size()) {
 | 
						|
    make_rtree_bggeom(mpts, &rtree);
 | 
						|
    for (typename Geom_type::iterator j = geom.begin(); j != geom.end(); ++j) {
 | 
						|
      BG_box box;
 | 
						|
      boost::geometry::envelope(*j, box);
 | 
						|
 | 
						|
      /*
 | 
						|
        For each component *j in geom, find points in mpts who intersect
 | 
						|
        with MBR(*j), such points are likely to intersect *j, the rest are
 | 
						|
        for sure disjoint *j thus no need to check precisely.
 | 
						|
      */
 | 
						|
      for (Rtree_index::const_query_iterator i =
 | 
						|
               rtree.qbegin(bgi::intersects(box));
 | 
						|
           i != rtree.qend(); ++i) {
 | 
						|
        /*
 | 
						|
          If *i really intersect *j, we have the result as false;
 | 
						|
          If no *i intersects *j, *j disjoint mpts.
 | 
						|
          And if no *j intersect mpts, we can conclude that mpts disjoint geom.
 | 
						|
        */
 | 
						|
        if (!boost::geometry::disjoint(mpts[i->second], *j)) return 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    make_rtree_bggeom(geom, &rtree);
 | 
						|
    for (typename Multipoint::iterator j = mpts.begin(); j != mpts.end(); ++j) {
 | 
						|
      BG_box box;
 | 
						|
      boost::geometry::envelope(*j, box);
 | 
						|
 | 
						|
      /*
 | 
						|
        For each point *j in mpts, find components *i in geom such that
 | 
						|
        MBR(*i) intersect *j, such *i are likely to intersect *j, the rest are
 | 
						|
        for sure disjoint *j thus no need to check precisely.
 | 
						|
      */
 | 
						|
      for (Rtree_index::const_query_iterator i =
 | 
						|
               rtree.qbegin(bgi::intersects(box));
 | 
						|
           i != rtree.qend(); ++i) {
 | 
						|
        /*
 | 
						|
          If *i really intersect *j, we have the result as false;
 | 
						|
          If no *i intersects *j, *j disjoint geom.
 | 
						|
          And if no *j intersect geom, we can conclude that mpts disjoint geom.
 | 
						|
        */
 | 
						|
        if (!boost::geometry::disjoint(geom[i->second], *j)) return 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'linestring disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a linestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::linestring_disjoint_geometry(Geometry *g1,
 | 
						|
                                                      Geometry *g2,
 | 
						|
                                                      bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, disjoint, Linestring, g1, Linestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, disjoint, Linestring, g1, Multilinestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point)
 | 
						|
    BGCALL(result, disjoint, Linestring, g1, Point, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipoint)
 | 
						|
    result = multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, disjoint, Linestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, disjoint, Linestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multilinestring disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multilinestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_disjoint_geometry(Geometry *g1,
 | 
						|
                                                           Geometry *g2,
 | 
						|
                                                           bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_linestring)
 | 
						|
    result =
 | 
						|
        BG_wrap<Geom_types>::linestring_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, disjoint, Multilinestring, g1, Multilinestring, g2,
 | 
						|
           pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_point)
 | 
						|
    BGCALL(result, disjoint, Multilinestring, g1, Point, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipoint)
 | 
						|
    result = multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, disjoint, Multilinestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, disjoint, Multilinestring, g1, Multipolygon, g2,
 | 
						|
           pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'point disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a point.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::point_disjoint_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                 bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, disjoint, Point, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, disjoint, Point, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, disjoint, Point, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint: {
 | 
						|
      Multipoint mpts(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                      g2->get_srid());
 | 
						|
      Point pt(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
               g1->get_srid());
 | 
						|
 | 
						|
      Point_set ptset(mpts.begin(), mpts.end());
 | 
						|
      result = (ptset.find(pt) == ptset.end());
 | 
						|
    } break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, disjoint, Point, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, disjoint, Point, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'polygon disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a polygon.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::polygon_disjoint_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                   bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, disjoint, Polygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, disjoint, Polygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, disjoint, Polygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, disjoint, Polygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, disjoint, Polygon, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipolygon disjoint xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipolygon.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipolygon_disjoint_geometry(Geometry *g1,
 | 
						|
                                                        Geometry *g2,
 | 
						|
                                                        bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, disjoint, Multipolygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, disjoint, Multipolygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, disjoint, Multipolygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, disjoint, Multipolygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, disjoint, Multipolygon, g1, Multilinestring, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'point intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a point.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::point_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                   bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, intersects, Point, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      result = !point_disjoint_geometry(g1, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, intersects, Point, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, intersects, Point, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_intersects_geometry(Geometry *g1,
 | 
						|
                                                        Geometry *g2,
 | 
						|
                                                        bool *pnull_value) {
 | 
						|
  return !multipoint_disjoint_geometry(g1, g2, pnull_value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'linestring intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a linestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::linestring_intersects_geometry(Geometry *g1,
 | 
						|
                                                        Geometry *g2,
 | 
						|
                                                        bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_point)
 | 
						|
    BGCALL(result, intersects, Linestring, g1, Point, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipoint)
 | 
						|
    result = multipoint_intersects_geometry(g2, g1, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, intersects, Linestring, g1, Linestring, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, intersects, Linestring, g1, Multilinestring, g2,
 | 
						|
           pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, intersects, Linestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, intersects, Linestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multilinestring intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multilinestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_intersects_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  if (gt2 == Geometry::wkb_point)
 | 
						|
    BGCALL(result, intersects, Multilinestring, g1, Point, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipoint)
 | 
						|
    result = multipoint_intersects_geometry(g2, g1, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_linestring)
 | 
						|
    BGCALL(result, intersects, Multilinestring, g1, Linestring, g2,
 | 
						|
           pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multilinestring)
 | 
						|
    BGCALL(result, intersects, Multilinestring, g1, Multilinestring, g2,
 | 
						|
           pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_polygon)
 | 
						|
    BGCALL(result, intersects, Multilinestring, g1, Polygon, g2, pnull_value);
 | 
						|
  else if (gt2 == Geometry::wkb_multipolygon)
 | 
						|
    BGCALL(result, intersects, Multilinestring, g1, Multipolygon, g2,
 | 
						|
           pnull_value);
 | 
						|
  else
 | 
						|
    DBUG_ASSERT(false);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'polygon intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a polygon.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::polygon_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                     bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, intersects, Polygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = !multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, intersects, Polygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, intersects, Polygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, intersects, Polygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, intersects, Polygon, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipolygon intersects xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipolygon.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipolygon_intersects_geometry(Geometry *g1,
 | 
						|
                                                          Geometry *g2,
 | 
						|
                                                          bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, intersects, Multipolygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = !multipoint_disjoint_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, intersects, Multipolygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, intersects, Multipolygon, g1, Multipolygon, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, intersects, Multipolygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, intersects, Multipolygon, g1, Multilinestring, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'linestring crosses xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a linestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::linestring_crosses_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                     bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, crosses, Linestring, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, crosses, Linestring, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, crosses, Linestring, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, crosses, Linestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multilinestring crosses xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multilinestring.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_crosses_geometry(Geometry *g1,
 | 
						|
                                                          Geometry *g2,
 | 
						|
                                                          bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, crosses, Multilinestring, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, crosses, Multilinestring, g1, Multilinestring, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, crosses, Multilinestring, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, crosses, Multilinestring, g1, Multipolygon, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint crosses xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_crosses_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                     bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
    case Geometry::wkb_multipolygon: {
 | 
						|
      bool has_in = false, has_out = false;
 | 
						|
      int res = 0;
 | 
						|
 | 
						|
      Multipoint mpts(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                      g1->get_srid());
 | 
						|
      /*
 | 
						|
        According to OGC's definition to crosses, if some Points of
 | 
						|
        g1 is in g2 and some are not, g1 crosses g2, otherwise not.
 | 
						|
       */
 | 
						|
      for (typename Multipoint::iterator i = mpts.begin();
 | 
						|
           i != mpts.end() && !(has_in && has_out); ++i) {
 | 
						|
        if (!has_out) {
 | 
						|
          res = point_disjoint_geometry(&(*i), g2, pnull_value);
 | 
						|
 | 
						|
          if (!*pnull_value) {
 | 
						|
            has_out = res;
 | 
						|
            if (has_out) continue;
 | 
						|
          } else
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!has_in) {
 | 
						|
          res = point_within_geometry(&(*i), g2, pnull_value);
 | 
						|
          if (!*pnull_value)
 | 
						|
            has_in = res;
 | 
						|
          else
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      result = (has_in && has_out);
 | 
						|
    } break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint crosses xxx'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, not a geometry collection.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_overlaps_multipoint(Geometry *g1,
 | 
						|
                                                        Geometry *g2) {
 | 
						|
  int result = 0;
 | 
						|
 | 
						|
  Multipoint mpts1(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                   g1->get_srid());
 | 
						|
  Multipoint mpts2(g2->get_data_ptr(), g2->get_data_size(), g2->get_flags(),
 | 
						|
                   g2->get_srid());
 | 
						|
  Point_set ptset1, ptset2;
 | 
						|
 | 
						|
  ptset1.insert(mpts1.begin(), mpts1.end());
 | 
						|
  ptset2.insert(mpts2.begin(), mpts2.end());
 | 
						|
 | 
						|
  // They overlap if they intersect and also each has some points that the other
 | 
						|
  // one doesn't have.
 | 
						|
  Point_vector respts;
 | 
						|
  typename Point_vector::iterator endpos;
 | 
						|
  size_t ptset1sz = ptset1.size(), ptset2sz = ptset2.size(), resptssz;
 | 
						|
 | 
						|
  respts.resize(ptset1sz > ptset2sz ? ptset1sz : ptset2sz);
 | 
						|
  endpos = std::set_intersection(ptset1.begin(), ptset1.end(), ptset2.begin(),
 | 
						|
                                 ptset2.end(), respts.begin(), bgpt_lt());
 | 
						|
  resptssz = endpos - respts.begin();
 | 
						|
  if (resptssz > 0 && resptssz < ptset1.size() && resptssz < ptset2.size())
 | 
						|
    result = 1;
 | 
						|
  else
 | 
						|
    result = 0;
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multilinestring touches polygon'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multilinestring.
 | 
						|
  @param g2 Second Geometry operand, a polygon.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_touches_polygon(Geometry *g1,
 | 
						|
                                                         Geometry *g2,
 | 
						|
                                                         bool *pnull_value) {
 | 
						|
  const void *data_ptr = g2->normalize_ring_order();
 | 
						|
  if (data_ptr == NULL) {
 | 
						|
    *pnull_value = true;
 | 
						|
    my_error(ER_GIS_INVALID_DATA, MYF(0), "st_touches");
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  Polygon plgn(data_ptr, g2->get_data_size(), g2->get_flags(), g2->get_srid());
 | 
						|
  Multilinestring mls(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                      g1->get_srid());
 | 
						|
 | 
						|
  Multipolygon mplgn;
 | 
						|
  mplgn.push_back(plgn);
 | 
						|
 | 
						|
  int result = boost::geometry::touches(mls, mplgn);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'point touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a point.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::point_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, touches, Point, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, touches, Point, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, touches, Point, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, touches, Point, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipoint touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipoint.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipoint_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                     bool *pnull_value) {
 | 
						|
  int has_touches = 0;
 | 
						|
 | 
						|
  Multipoint mpts(g1->get_data_ptr(), g1->get_data_size(), g1->get_flags(),
 | 
						|
                  g1->get_srid());
 | 
						|
  for (typename Multipoint::iterator i = mpts.begin(); i != mpts.end(); ++i) {
 | 
						|
    int ptg = point_touches_geometry(&(*i), g2, pnull_value);
 | 
						|
    if (*pnull_value) return 0;
 | 
						|
    if (ptg)
 | 
						|
      has_touches = 1;
 | 
						|
    else if (!point_disjoint_geometry(&(*i), g2, pnull_value))
 | 
						|
      return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return has_touches;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'linestring touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a linestring.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::linestring_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                     bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, touches, Linestring, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_touches_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, touches, Linestring, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, touches, Linestring, g1, Multilinestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, touches, Linestring, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, touches, Linestring, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multilinestring touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multilinestring.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multilinestring_touches_geometry(Geometry *g1,
 | 
						|
                                                          Geometry *g2,
 | 
						|
                                                          bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, touches, Multilinestring, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_touches_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, touches, Multilinestring, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, touches, Multilinestring, g1, Multilinestring, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      result = BG_wrap<Geom_types>::multilinestring_touches_polygon(
 | 
						|
          g1, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, touches, Multilinestring, g1, Multipolygon, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'polygon touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a polygon.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::polygon_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                                  bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, touches, Polygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_touches_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, touches, Polygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, touches, Polygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, touches, Polygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      result = BG_wrap<Geom_types>::multilinestring_touches_polygon(
 | 
						|
          g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatcher for 'multipolygon touches geometry'.
 | 
						|
 | 
						|
  @tparam Geom_types Geometry types definitions.
 | 
						|
  @param g1 First Geometry operand, a multipolygon.
 | 
						|
  @param g2 Second Geometry operand, a geometry other than geometry collection.
 | 
						|
  @param[out] pnull_value Returns whether error occurred duirng the computation.
 | 
						|
  @return 0 if specified relation doesn't hold for the given operands,
 | 
						|
                otherwise returns none 0.
 | 
						|
 */
 | 
						|
template <typename Geom_types>
 | 
						|
int BG_wrap<Geom_types>::multipolygon_touches_geometry(Geometry *g1,
 | 
						|
                                                       Geometry *g2,
 | 
						|
                                                       bool *pnull_value) {
 | 
						|
  int result = 0;
 | 
						|
  Geometry::wkbType gt2 = g2->get_type();
 | 
						|
 | 
						|
  switch (gt2) {
 | 
						|
    case Geometry::wkb_point:
 | 
						|
      BGCALL(result, touches, Multipolygon, g1, Point, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipoint:
 | 
						|
      result = multipoint_touches_geometry(g2, g1, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_polygon:
 | 
						|
      BGCALL(result, touches, Multipolygon, g1, Polygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multipolygon:
 | 
						|
      BGCALL(result, touches, Multipolygon, g1, Multipolygon, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_linestring:
 | 
						|
      BGCALL(result, touches, Multipolygon, g1, Linestring, g2, pnull_value);
 | 
						|
      break;
 | 
						|
    case Geometry::wkb_multilinestring:
 | 
						|
      BGCALL(result, touches, Multipolygon, g1, Multilinestring, g2,
 | 
						|
             pnull_value);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      DBUG_ASSERT(false);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Explicit template instantiations are needed here.
 | 
						|
  Templates were moved to separate file in order to avoid
 | 
						|
  inlining and out-of-memory problems in optmized mode on gcc/solaris/intel.
 | 
						|
 */
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::point_within_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::multipoint_within_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::linestring_within_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_within_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                    bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::polygon_within_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipolygon_within_geometry(Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::multipoint_equals_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::point_disjoint_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipoint_disjoint_geometry(Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    linestring_disjoint_geometry(Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_disjoint_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                      bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::polygon_disjoint_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipolygon_disjoint_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                   bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::point_intersects_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipoint_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                   bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    linestring_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                   bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                        bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::polygon_intersects_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipolygon_intersects_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                     bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::linestring_crosses_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::multipoint_crosses_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_crosses_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                     bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipoint_overlaps_multipoint(Geometry *g1, Geometry *g2);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::point_touches_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::multipoint_touches_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::linestring_touches_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_touches_polygon(Geometry *g1, Geometry *g2,
 | 
						|
                                    bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multilinestring_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                     bool *pnull_value);
 | 
						|
template int
 | 
						|
BG_wrap<BG_models<boost::geometry::cs::cartesian>>::polygon_touches_geometry(
 | 
						|
    Geometry *g1, Geometry *g2, bool *pnull_value);
 | 
						|
template int BG_wrap<BG_models<boost::geometry::cs::cartesian>>::
 | 
						|
    multipolygon_touches_geometry(Geometry *g1, Geometry *g2,
 | 
						|
                                  bool *pnull_value);
 |