~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/core/spatialindex/geometry/Point.cc

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Tools Library
 
2
//
 
3
// Copyright (C) 2004  Navel Ltd.
 
4
//
 
5
// This library is free software; you can redistribute it and/or
 
6
// modify it under the terms of the GNU Lesser General Public
 
7
// License as published by the Free Software Foundation; either
 
8
// version 2.1 of the License, or (at your option) any later version.
 
9
//
 
10
// This library is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
// Lesser General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU Lesser General Public
 
16
// License along with this library; if not, write to the Free Software
 
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
//
 
19
//  Email:
 
20
//    mhadji@gmail.com
 
21
 
 
22
#include <cstring>
 
23
#include <limits>
 
24
#include <Tools.h>
 
25
 
 
26
Tools::Geometry::Point::Point()
 
27
    : m_dimension( 0 ), m_pCoords( 0 )
 
28
{
 
29
}
 
30
 
 
31
Tools::Geometry::Point::Point( const double* pCoords, unsigned long dimension )
 
32
    : m_dimension( dimension )
 
33
{
 
34
  // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
 
35
 
 
36
  m_pCoords = new double[m_dimension];
 
37
  memcpy( m_pCoords, pCoords, m_dimension * sizeof( double ) );
 
38
}
 
39
 
 
40
Tools::Geometry::Point::Point( const Point& p )
 
41
    : m_dimension( p.m_dimension )
 
42
{
 
43
  // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
 
44
 
 
45
  m_pCoords = new double[m_dimension];
 
46
  memcpy( m_pCoords, p.m_pCoords, m_dimension * sizeof( double ) );
 
47
}
 
48
 
 
49
Tools::Geometry::Point::~Point()
 
50
{
 
51
  delete[] m_pCoords;
 
52
}
 
53
 
 
54
Tools::Geometry::Point& Tools::Geometry::Point::operator=( const Point & p )
 
55
{
 
56
  if ( this != &p )
 
57
  {
 
58
    makeDimension( p.m_dimension );
 
59
    memcpy( m_pCoords, p.m_pCoords, m_dimension * sizeof( double ) );
 
60
  }
 
61
 
 
62
  return *this;
 
63
}
 
64
 
 
65
bool Tools::Geometry::Point::operator==( const Point& p ) const
 
66
{
 
67
  if ( m_dimension != p.m_dimension )
 
68
    throw IllegalArgumentException(
 
69
      "Tools::Geometry::Point::operator==: Points have different number of dimensions."
 
70
    );
 
71
 
 
72
  for ( unsigned long i = 0; i < m_dimension; i++ )
 
73
  {
 
74
    if (
 
75
      m_pCoords[i] < p.m_pCoords[i] - std::numeric_limits<double>::epsilon() ||
 
76
      m_pCoords[i] > p.m_pCoords[i] + std::numeric_limits<double>::epsilon() )  return false;
 
77
  }
 
78
 
 
79
  return true;
 
80
}
 
81
 
 
82
//
 
83
// IObject interface
 
84
//
 
85
Tools::Geometry::Point* Tools::Geometry::Point::clone()
 
86
{
 
87
  return new Point( *this );
 
88
}
 
89
 
 
90
//
 
91
// ISerializable interface
 
92
//
 
93
unsigned long Tools::Geometry::Point::getByteArraySize()
 
94
{
 
95
  return ( sizeof( unsigned long ) + m_dimension * sizeof( double ) );
 
96
}
 
97
 
 
98
void Tools::Geometry::Point::loadFromByteArray( const byte* ptr )
 
99
{
 
100
  unsigned long dimension;
 
101
  memcpy( &dimension, ptr, sizeof( unsigned long ) );
 
102
  ptr += sizeof( unsigned long );
 
103
 
 
104
  makeDimension( dimension );
 
105
  memcpy( m_pCoords, ptr, m_dimension * sizeof( double ) );
 
106
  //ptr += m_dimension * sizeof(double);
 
107
}
 
108
 
 
109
void Tools::Geometry::Point::storeToByteArray( byte** data, unsigned long& len )
 
110
{
 
111
  len = getByteArraySize();
 
112
  *data = new byte[len];
 
113
  byte* ptr = *data;
 
114
 
 
115
  memcpy( ptr, &m_dimension, sizeof( unsigned long ) );
 
116
  ptr += sizeof( unsigned long );
 
117
  memcpy( ptr, m_pCoords, m_dimension * sizeof( double ) );
 
118
  //ptr += m_dimension * sizeof(double);
 
119
}
 
120
 
 
121
//
 
122
// IShape interface
 
123
//
 
124
bool Tools::Geometry::Point::intersectsShape( const IShape& s ) const
 
125
{
 
126
  const Region* pr = dynamic_cast<const Region*>( &s );
 
127
  if ( pr != 0 )
 
128
  {
 
129
    return pr->containsPoint( *this );
 
130
  }
 
131
 
 
132
  throw IllegalStateException(
 
133
    "Tools::Geometry::Point::intersectsShape: Not implemented yet!"
 
134
  );
 
135
}
 
136
 
 
137
bool Tools::Geometry::Point::containsShape( const IShape& s ) const
 
138
{
 
139
  return false;
 
140
}
 
141
 
 
142
bool Tools::Geometry::Point::touchesShape( const IShape& s ) const
 
143
{
 
144
  const Point* ppt = dynamic_cast<const Point*>( &s );
 
145
  if ( ppt != 0 )
 
146
  {
 
147
    if ( *this == *ppt ) return true;
 
148
    return false;
 
149
  }
 
150
 
 
151
  const Region* pr = dynamic_cast<const Region*>( &s );
 
152
  if ( pr != 0 )
 
153
  {
 
154
    return pr->touchesPoint( *this );
 
155
  }
 
156
 
 
157
  throw IllegalStateException(
 
158
    "Tools::Geometry::Point::touchesShape: Not implemented yet!"
 
159
  );
 
160
}
 
161
 
 
162
void Tools::Geometry::Point::getCenter( Point& out ) const
 
163
{
 
164
  out = *this;
 
165
}
 
166
 
 
167
unsigned long Tools::Geometry::Point::getDimension() const
 
168
{
 
169
  return m_dimension;
 
170
}
 
171
 
 
172
void Tools::Geometry::Point::getMBR( Region& out ) const
 
173
{
 
174
  out = Region( m_pCoords, m_pCoords, m_dimension );
 
175
}
 
176
 
 
177
double Tools::Geometry::Point::getArea() const
 
178
{
 
179
  return 0.0;
 
180
}
 
181
 
 
182
double Tools::Geometry::Point::getMinimumDistance( const IShape& s ) const
 
183
{
 
184
  const Point* ppt = dynamic_cast<const Point*>( &s );
 
185
  if ( ppt != 0 )
 
186
  {
 
187
    return getMinimumDistance( *ppt );
 
188
  }
 
189
 
 
190
  const Region* pr = dynamic_cast<const Region*>( &s );
 
191
  if ( pr != 0 )
 
192
  {
 
193
    return pr->getMinimumDistance( *this );
 
194
  }
 
195
 
 
196
  throw IllegalStateException(
 
197
    "Tools::Geometry::Point::getMinimumDistance: Not implemented yet!"
 
198
  );
 
199
}
 
200
 
 
201
double Tools::Geometry::Point::getMinimumDistance( const Point& p ) const
 
202
{
 
203
  if ( m_dimension != p.m_dimension )
 
204
    throw IllegalArgumentException(
 
205
      "Tools::Geometry::Point::getMinimumDistance: Shapes have different number of dimensions."
 
206
    );
 
207
 
 
208
  double ret = 0.0;
 
209
 
 
210
  for ( unsigned long cDim = 0; cDim < m_dimension; cDim++ )
 
211
  {
 
212
    ret += std::pow( m_pCoords[cDim] - p.m_pCoords[cDim], 2.0 );
 
213
  }
 
214
 
 
215
  return std::sqrt( ret );
 
216
}
 
217
 
 
218
double Tools::Geometry::Point::getCoordinate( unsigned long index ) const
 
219
{
 
220
  if ( index < 0 || index >= m_dimension )
 
221
    throw IndexOutOfBoundsException( index );
 
222
 
 
223
  return m_pCoords[index];
 
224
}
 
225
 
 
226
void Tools::Geometry::Point::makeInfinite( unsigned long dimension )
 
227
{
 
228
  makeDimension( dimension );
 
229
  for ( unsigned long cIndex = 0; cIndex < m_dimension; cIndex++ )
 
230
  {
 
231
    m_pCoords[cIndex] = std::numeric_limits<double>::max();
 
232
  }
 
233
}
 
234
 
 
235
void Tools::Geometry::Point::makeDimension( unsigned long dimension )
 
236
{
 
237
  if ( m_dimension != dimension )
 
238
  {
 
239
    delete[] m_pCoords;
 
240
 
 
241
    // remember that this is not a constructor. The object will be destructed normally if
 
242
    // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
 
243
    m_pCoords = 0;
 
244
 
 
245
    m_dimension = dimension;
 
246
    m_pCoords = new double[m_dimension];
 
247
  }
 
248
}
 
249
 
 
250
std::ostream& Tools::Geometry::operator<<( std::ostream& os, const Point& pt )
 
251
{
 
252
  for ( unsigned long cDim = 0; cDim < pt.m_dimension; cDim++ )
 
253
  {
 
254
    os << pt.m_pCoords[cDim] << " ";
 
255
  }
 
256
 
 
257
  return os;
 
258
}