Advertisement
MagnusArias

SBO | nPoint C#

Jan 11th, 2020
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.13 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Data.SqlTypes;
  5. using System.Text;
  6. using System.Globalization;
  7. using Microsoft.SqlServer.Server;
  8. using Microsoft.SqlServer.Types;
  9.  
  10. [Serializable]
  11. [SqlUserDefinedType(Format.UserDefined,
  12.      IsByteOrdered = true,
  13.     ValidationMethodName = "ValidatePoint",
  14.     MaxByteSize = 2000)]
  15. public struct nPoint : INullable, IBinarySerialize
  16. {
  17.     private bool is_Null;
  18.     private ArrayList coordinates;
  19.  
  20.     // konstruktor
  21.     public nPoint(SqlString s)
  22.     {
  23.         is_Null = false;
  24.         coordinates = new ArrayList();
  25.         CultureInfo ci = new CultureInfo("en-US");
  26.         double dblVal;
  27.         char[] separator = { ',' };
  28.         string[] _wspolrzedne = s.Value.Split(separator);
  29.         for (int i = 0; i < _wspolrzedne.Length; i++)
  30.         {
  31.             try
  32.             {
  33.                 dblVal = Double.Parse(_wspolrzedne[i], ci);
  34.                 coordinates.Add(dblVal);
  35.             }
  36.             catch (Exception ex)
  37.             {
  38.                 throw new ArgumentException("Błąd konwersji:\n" + ex.Message);
  39.             }
  40.         }
  41.     }
  42.  
  43.     public bool IsNull
  44.     {
  45.         get
  46.         {
  47.             return (is_Null);
  48.         }
  49.     }
  50.  
  51.     public static nPoint Null
  52.     {
  53.         get
  54.         {
  55.             nPoint pt = new nPoint();
  56.             pt.is_Null = true;
  57.             return pt;
  58.         }
  59.     }
  60.  
  61.     public void Read(BinaryReader r)
  62.     {
  63.         CultureInfo ci = new CultureInfo("en-US");
  64.         int size = r.ReadInt32();
  65.         coordinates = new ArrayList();
  66.         for (int i = 0; i < size; i++)
  67.             coordinates.Add(r.ReadDouble());
  68.     }
  69.  
  70.     public void Write(BinaryWriter w)
  71.     {
  72.         w.Write(coordinates.Count);
  73.         for (int i = 0; i < coordinates.Count; i++)
  74.             w.Write((double)coordinates[i]);
  75.     }
  76.  
  77.     public override string ToString()
  78.     {
  79.         if (this.IsNull)
  80.             return "NULL";
  81.         else
  82.         {
  83.             double dbl;
  84.             StringBuilder builder = new StringBuilder();
  85.             for (int i = 0; i < coordinates.Count; i++)
  86.             {
  87.                 CultureInfo ci = new CultureInfo("en-US");
  88.                 dbl = (double)coordinates[i];
  89.                 builder.Append(dbl.ToString(ci));
  90.                 if (i != coordinates.Count - 1) builder.Append(",");
  91.             }
  92.             return builder.ToString();
  93.         }
  94.     }
  95.  
  96.     [SqlMethod(OnNullCall = false)]
  97.     public static nPoint Parse(SqlString s)
  98.     {
  99.         if (s.IsNull || s == "")
  100.             return Null;
  101.  
  102.         // Rozdziela przesłany łańcuch na poszczególne liczby typu double
  103.         nPoint pt = new nPoint(s);
  104.  
  105.         // Przeprowadza walidację punktu (tutaj zbędna, bo każda liczba typu double
  106.         // jest prawidłowa, ale istnienie jakiejś metody walidacyjnej jest wymagane)
  107.         if (!pt.ValidatePoint())
  108.             throw new ArgumentException("Nieprawidłowe wartości współrzędnych.");
  109.         return pt;
  110.     }
  111.  
  112.     [SqlMethod(OnNullCall = false)]
  113.     public double Coordinate(SqlInt32 i)
  114.     {
  115.         int k = i.Value;
  116.         if (k < 0 || k >= coordinates.Count)
  117.             throw new ArgumentException("Nieprawidłowa wartość indeksu współrzędnej.");
  118.         else
  119.         {
  120.             return ((Double)coordinates[k]);
  121.         }
  122.     }
  123.  
  124.     // Metoda walidująca współrzędne punktów
  125.     private bool ValidatePoint()
  126.     {
  127.         return true;
  128.     }
  129.     public int Size
  130.     {
  131.         get
  132.         {
  133.             return (coordinates.Count);
  134.         }
  135.     }
  136.  
  137.     // Metoda zwraca współrzędne jako string (get) i ustawia nowe z przesłanego stringa (set)
  138.     public SqlString Coordinates
  139.     {
  140.         get
  141.         {
  142.             return ToString();
  143.         }
  144.         set
  145.         {
  146.             coordinates = new ArrayList();
  147.             CultureInfo ci = new CultureInfo("en-US");
  148.             double dblVal;
  149.             char[] separator = { ',' };
  150.             string[] _wspolrzedne = value.Value.Split(separator);
  151.             for (int i = 0; i < _wspolrzedne.Length; i++)
  152.             {
  153.                 try
  154.                 {
  155.                     dblVal = Double.Parse(_wspolrzedne[i], ci);
  156.                     coordinates.Add(dblVal);
  157.                 }
  158.                 catch (Exception ex)
  159.                 {
  160.                     throw new ArgumentException("Błąd konwersji:\n" + ex.Message);
  161.                 }
  162.             }
  163.         }
  164.     }
  165.  
  166.     // Metoda przesuwa punkt o wektor, którego współrzędne przekazujemy parameterm jako SqlString
  167.     [SqlMethod(OnNullCall = false)]
  168.     public SqlString Przesun(SqlString wektor)
  169.     {
  170.         char[] separator = { ',' };
  171.         string[] _wspolrzedne = wektor.Value.Split(separator);
  172.         if (_wspolrzedne.Length > coordinates.Count)
  173.             throw new ArgumentException("Zbyt duża liczba współrzędnych.");
  174.         ArrayList _coordinates = new ArrayList();
  175.         CultureInfo ci = new CultureInfo("en-US");
  176.         double dblVal;
  177.         for (int i = 0; i < _wspolrzedne.Length; i++)
  178.         {
  179.             try
  180.             {
  181.                 dblVal = Double.Parse(_wspolrzedne[i], ci);
  182.                 _coordinates.Add(dblVal);
  183.             }
  184.             catch (Exception ex)
  185.             {
  186.                 throw new ArgumentException("Błąd konwersji:\n" + ex.Message);
  187.             }
  188.         }
  189.         for (int i = 0; i < _coordinates.Count; i++)
  190.         {
  191.             coordinates[i] = (double)coordinates[i] + (double)_coordinates[i];
  192.         }
  193.         return new SqlString(ToString());
  194.     }
  195.  
  196.     // Metoda przesuwa punkt o wektor, którego współrzędne przekazujemy parameterm jako nPoint
  197.     [SqlMethod(OnNullCall = false)]
  198.     public SqlString PrzesunP(nPoint p)
  199.     {
  200.         if (p.Size > Size)
  201.             throw new ArgumentException("Zbyt duża liczba współrzędnych punktu będącego wektorem przesunięcia.");
  202.         for (int i = 0; i < p.Size; i++)
  203.         {
  204.             coordinates[i] = (double)coordinates[i] + (double)p.coordinates[i];
  205.         }
  206.         return new SqlString(ToString());
  207.     }
  208.  
  209.     // Metoda obliczająca odległość od początku układu współrzędnych do danego punktu.
  210.     [SqlMethod(OnNullCall = false)]
  211.     public Double Distance()
  212.     {
  213.         double suma = 0;
  214.         for (int i = 0; i < coordinates.Count; i++)
  215.             suma += Math.Pow((double)coordinates[i], 2);
  216.         return Math.Pow(suma, 0.5);
  217.     }
  218.  
  219.     // Metoda obliczająca odległość od danego punktu do punktu przesłanego jako argument.
  220.     [SqlMethod(OnNullCall = false)]
  221.     public Double DistanceFrom(nPoint p)
  222.     {
  223.         if (Size != p.Size)
  224.             throw new Exception("Niezgodne wymiary punktów!\n" +
  225.                                 "Nie można obliczyć odległości, jeśli punkt źródłowy " +
  226.                                 "i docelowy nie mają tego samego wymiaru.");
  227.         double suma = 0;
  228.         for (int i = 0; i < coordinates.Count; i++)
  229.             suma += Math.Pow((double)coordinates[i] - (double)p.coordinates[i], 2);
  230.         return Math.Pow(suma, 0.5);
  231.     }
  232.  
  233.     // Metoda obliczająca odległość od danego punktu do punktu o współrzędnych przesłanych jako argument
  234.     [SqlMethod(OnNullCall = false)]
  235.     public Double DistanceFromCoordinates(SqlString s)
  236.     {
  237.         char[] separator = { ',' };
  238.         string[] _wspolrzedne = s.Value.Split(separator);
  239.         if (_wspolrzedne.Length > Size)
  240.             throw new ArgumentException("Zbyt duża liczba współrzędnych.\n" +
  241.                 "Przesłana liczba współrzędnych musi być mniejsza lub " +
  242.                 "równa wymiarowi punktu.");
  243.         CultureInfo ci = new CultureInfo("en-US");
  244.         double dblVal, suma = 0;
  245.         for (int i = 0; i < Size; i++)
  246.         {
  247.             if (i < _wspolrzedne.Length)
  248.             {
  249.                 try
  250.                 {
  251.                     dblVal = Double.Parse(_wspolrzedne[i], ci);
  252.                     suma += Math.Pow((double)coordinates[i] - dblVal, 2);
  253.                 }
  254.                 catch (Exception ex)
  255.                 {
  256.                     throw new ArgumentException("Błąd konwersji:\n" + ex.Message);
  257.                 }
  258.             }
  259.             else
  260.             {
  261.                 // przyjmujemy, że dalsze współrzędne (nie przesłane) wynoszą 0
  262.                 suma += Math.Pow((double)coordinates[i], 2);
  263.             }
  264.         }
  265.         return Math.Pow(suma, 0.5);
  266.     }
  267.     public SqlGeometry ToSpatial()
  268.     {
  269.  
  270.         double dbl;
  271.         StringBuilder builder = new StringBuilder();
  272.         for (int i = 0; i < coordinates.Count; i++)
  273.         {
  274.             CultureInfo ci = new CultureInfo("en-US");
  275.             dbl = (double)coordinates[i];
  276.             builder.Append(dbl.ToString(ci));
  277.             if (i != coordinates.Count - 1) builder.Append(" ");
  278.         }
  279.  
  280.         SqlGeometry sqlg =
  281.             SqlGeometry.STGeomFromText(new SqlChars
  282.                 (new SqlString("POINT (" + builder.ToString() + ")")), 0);
  283.  
  284.         return sqlg;
  285.     }
  286.  
  287.     public SqlGeometry ToSpatialWithR(double r)
  288.     {
  289.         return this.ToSpatial().STBuffer(r);
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement