context: // ********************************************************************************************************
  // Product Name: DotSpatial.Topology.dll
  // Description:  The basic topology module for the new dotSpatial libraries
  // ********************************************************************************************************
  // The contents of this file are subject to the Lesser GNU Public License (LGPL)
  // you may not use this file except in compliance with the License. You may obtain a copy of the License at
  // http://dotspatial.codeplex.com/license  Alternately, you can access an earlier version of this content from
  // the Net Topology Suite, which is also protected by the GNU Lesser Public License and the sourcecode
  // for the Net Topology Suite can be obtained here: http://sourceforge.net/projects/nts.
  //
  // Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
  // ANY KIND, either expressed or implied. See the License for the specific language governing rights and
  // limitations under the License.
  //
  // The Original Code is from the Net Topology Suite, which is a C# port of the Java Topology Suite.
  //
  // The Initial Developer to integrate this code into MapWindow 6.0 is Ted Dunsford.
  //
  // Contributor(s): (Open source contributors should list themselves and their modifications here).
  // |         Name         |    Date    |                              Comment
  // |----------------------|------------|------------------------------------------------------------
  // |                      |            |
  // ********************************************************************************************************
  
  using System;
  using System.ComponentModel;
  
  namespace DotSpatial.Topology
  {
      /// <summary>
      /// A lightweight class used to store coordinates
      /// on the 2-dimensional Cartesian plane.
      /// It is distinct from <c>Point</c>, which is a subclass of <c>Geometry</c>.
      /// Unlike objects of type <c>Point</c> (which contain additional
      /// information such as an envelope, a precision model, and spatial reference
      /// system information), a <c>Coordinate</c> only contains ordinate values
      /// and accessor methods.
      /// <c>Coordinate</c>s are two-dimensional points, with an additional
      /// z-ordinate. NTS does not support any operations on the z-ordinate except
      /// the basic accessor functions. Constructed coordinates will have a
      /// z-ordinate of <c>NaN</c>.  The standard comparison functions will ignore
      /// the z-ordinate.
      /// </summary>
      [Serializable, TypeConverter(typeof(ExpandableObjectConverter))]
      public sealed class CoordinateF
      {
          private float _m = float.NaN;
          private float _x = float.NaN;
          private float _y = float.NaN;
          private float _z = float.NaN;
  
          /// <summary>
          /// Creates a CoordinateF by using the X, Y and Z terms of a FloatVector
          /// </summary>
          /// <param name="floatVector"></param>
          public CoordinateF(FloatVector3 floatVector)
          {
              _x = floatVector.X;
              _y = floatVector.Y;
              _z = floatVector.Z;
              _m = float.NaN;
          }
  
          /// <summary>
          /// Constructs a <c>Coordinate</c> at (x, y, z).
          /// </summary>
          /// <param name="x">X value.</param>
          /// <param name="y">Y value.</param>
          /// <param name="z">Z value.</param>
          /// <param name="m">Measure value.</param>
          public CoordinateF(float x, float y, float z, float m)
          {
              _x = x;
              _y = y;
              _z = z;
              _m = m;
          }
  
          /// <summary>
          /// Constructs a <c>Coordinate</c> at (x, y, z).
          /// </summary>
          /// <param name="x">X value.</param>
          /// <param name="y">Y value.</param>
          /// <param name="z">Z value.</param>
          public CoordinateF(float x, float y, float z)
          {
              _x = x;
              _y = y;
              _z = z;
              _m = 0;
          }
  
          /// <summary>
          /// Creates a Coordinate from any ICoordinate Interface
          /// </summary>
          /// <param name="coordinate">The Vector.IPoint interface to construct a coordinate from</param>
          public CoordinateF(Coordinate coordinate)
          {
              _x = Convert.ToSingle(coordinate.X);
              _y = Convert.ToSingle(coordinate.Y);
              _z = Convert.ToSingle(coordinate.Z);
          }
  
          /// <summary>
          ///  Constructs a <c>Coordinate</c> at (0, 0, NaN).
          /// </summary>
          public CoordinateF() : this(0.0F, 0.0F, 0, 0) { }
  
          /// <summary>
          /// Constructs a <c>Coordinate</c> at (x, y, NaN).
          /// </summary>
          /// <param name="x">X value.</param>
          /// <param name="y">Y value.</param>
          public CoordinateF(float x, float y) : this(x, y, 0F, 0F) { }
  
          /// <summary>
          /// Direct access to the coordinate works as a float.  If you only have the interface,
          /// it must involve conversions to and from a float.  This may cause errors if the
          /// value being set is outside the range of the float values.
          /// </summary>
          public float X
          {
              get { return _x; }
              set { _x = value; }
          }
  
          /// <summary>
          /// Direct access to the Y coordinate as a float
          /// </summary>
          public float Y
          {
              get { return _y; }
              set { _y = value; }
          }
  
          /// <summary>
          /// Z coordinate.
          /// </summary>
          public float Z
          {
              get { return _z; }
              set { _z = value; }
          }
  
          /// <summary>
          /// A Measure coordinate
          /// </summary>
          public float M
          {
              get { return _m; }
              set { _m = value; }
          }
  
          /// <summary>
          /// Gets/Sets <c>Coordinate</c>s (x, y, z) values.
          /// </summary>
          [Browsable(false)]
          public CoordinateF CoordinateValue
          {
              get
              {
                  return this;
              }
              set
              {
                  _x = value.X;
                  _y = value.Y;
                  _z = value.Z;
                  _m = value.M;
              }
          }
  
          /// <summary>
          /// Gets or sets the double value corresponding to the specific ordinate
          /// </summary>
          /// <param name="index"></param>
          /// <returns></returns>
          public double this[int index]
          {
              get
              {
                  if (index == 0) return Convert.ToDouble(_x);
                  if (index == 1) return Convert.ToDouble(_y);
                  if (index == 2) return Convert.ToDouble(_z);
                  return 0;
              }
              set
              {
                  if (index == 0) _x = Convert.ToSingle(value);
                  if (index == 1) _y = Convert.ToSingle(value);
                  if (index == 2) _z = Convert.ToSingle(value);
              }
          }
  
          /// <summary>
          ///  For now this is 3D
          /// </summary>
          public int NumOrdinates
          {
              get { return 3; }
          }
  
          /// <summary>
          /// Gets or sets the values of this CoordinateF using an array of double values
          /// </summary>
          public double[] Values
          {
              get
              {
                  return new double[] { Convert.ToSingle(_x), Convert.ToSingle(_y), Convert.ToSingle(_z) };
              }
              set
              {
                  if (value.GetLength(0) > 0) _x = Convert.ToSingle(value[0]);
                  if (value.GetLength(0) > 1) _y = Convert.ToSingle(value[1]);
  
gt:                 if (value.GetLength(0) > 2) _z = Convert.ToSingle(value[2]);