Modify api documentation
[platform/core/csapi/tizenfx.git] / src / Tizen.Location / Tizen.Location / LocationBoundary.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Location
22 {
23     /// <summary>
24     /// Abstract class which provides functions related to geographic bounds information.
25     /// </summary>
26     public abstract class LocationBoundary : IDisposable
27     {
28         internal IntPtr handle;
29         private bool _disposed = false;
30
31         /// <summary>
32         /// Gets the location boundary type.
33         /// </summary>
34         public BoundaryType BoundaryType{ get; internal set; }
35
36         internal LocationBoundary() { }
37         /// <summary>
38         /// The destructor of LocationBoundary class.
39         /// </summary>
40         ~LocationBoundary()
41         {
42             Log.Info(Globals.LogTag, "The destructor of LocationBoundary class");
43             Dispose(false);
44         }
45
46         internal IntPtr GetHandle()
47         {
48             return handle;
49         }
50
51         /// <summary>
52         /// Checks if the boundary contains the specified geographical coordinates.
53         /// </summary>
54         /// <param name="coordinate"> The coordinate which needs to be checked.</param>
55         /// <returns>Returns a boolean value indicating whether or not the specified coordinate lies in the geographical area.</returns>
56         public bool BoundaryContainsCoordinates(Coordinate coordinate)
57         {
58             Log.Info(Globals.LogTag, "Checking if coordinates are contained within boundary");
59             return Interop.LocationBoundary.IsValidCoordinates(handle, coordinate);
60         }
61
62         /// <summary>
63         /// The overidden Dispose method of the IDisposable class.
64         /// </summary>
65         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
66         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
67         public void Dispose()
68         {
69             Log.Info(Globals.LogTag, "Dispose");
70             Dispose(true);
71             GC.SuppressFinalize(this);
72         }
73
74         protected virtual void Dispose(bool disposing)
75         {
76             Log.Info(Globals.LogTag, "Dispose");
77             if (_disposed)
78                 return;
79
80             if (disposing)
81                 DestroyHandle();
82
83             _disposed = true;
84         }
85
86         private void DestroyHandle()
87         {
88             Log.Info(Globals.LogTag, "DestroyBoundaryHandle");
89             int ret = Interop.LocationBoundary.DestroyBoundary(handle);
90             if (((LocationError)ret != LocationError.None))
91             {
92                 Log.Error(Globals.LogTag, "Error in DestroyBoundary handle" + (LocationError)ret);
93                 throw LocationErrorFactory.ThrowLocationException(ret);
94             }
95         }
96     }
97
98     /// <summary>
99     /// Class representing a rectangular location boundary.
100     /// Inherits the Abstract LocationBoundary class.
101     /// </summary>
102     public class RectangleBoundary : LocationBoundary
103     {
104         /// <summary>
105         /// Constructor of the Rectangle boundary class.
106         /// </summary>
107         /// <param name="topLeft"> The coordinate which constitute the top left handside of the rectangular boundary.</param>
108         /// <param name="bottomRight"> The coordinate which constitute the bottom right handside of the rectangular boundary.</param>
109         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
110         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
111         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
112         public RectangleBoundary(Coordinate topLeft, Coordinate bottomRight)
113         {
114             Log.Info(Globals.LogTag, "Calling RectangleBoundary constructor");
115             BoundaryType = BoundaryType.Rectangle;
116             IntPtr boundsHandle;
117             int ret = Interop.LocationBoundary.CreateRectangularBoundary(topLeft, bottomRight, out boundsHandle);
118             if ((LocationBoundError)ret != LocationBoundError.None)
119             {
120                 Log.Error(Globals.LogTag, "Error Creating Rectangular Boundary," + (LocationBoundError)ret);
121                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
122             }
123             handle = boundsHandle;
124         }
125
126         /// <summary>
127         /// Gets the Top Left handside coordinate of a rectangular boundary.
128         /// </summary>
129         public Coordinate TopLeft
130         {
131             get
132             {
133                 Log.Info(Globals.LogTag, "Calling to get CoordinateItem TopLeft");
134                 return GetRectangleCoordinate("TopLeft");
135             }
136         }
137
138         /// <summary>
139         /// Gets the Bottom Right handside coordinate of a rectangular boundary.
140         /// </summary>
141         public Coordinate BottomRight
142         {
143             get
144             {
145                 Log.Info(Globals.LogTag, "Calling to get CoordinateItem BottomRight");
146                 return GetRectangleCoordinate("BottomRight");
147             }
148         }
149
150         private Coordinate GetRectangleCoordinate(string tag)
151         {
152             Coordinate topLeft;
153             Coordinate bottomRight;
154
155             Interop.LocationBoundary.GetRectangleCoordinates(handle, out topLeft, out bottomRight);
156
157             if (tag.Equals("TopLeft"))
158             {
159                 return topLeft;
160             }
161             else
162             {
163                 return bottomRight;
164             }
165         }
166     }
167
168     /// <summary>
169     /// Class representing a circular location boundary.
170     /// Inherits the Abstract LocationBoundary class.
171     /// </summary>
172     public class CircleBoundary : LocationBoundary
173     {
174         /// <summary>
175         /// Constructor of the Circular boundary class.
176         /// </summary>
177         /// <param name="coordinate"> The coordinates which constitute the center of the circular boundary.</param>
178         /// <param name="radius"> The radius value of the circular boundary.</param>
179         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
180         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
181         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
182         public CircleBoundary(Coordinate coordinate, double radius)
183         {
184             Log.Info(Globals.LogTag, "Calling CircleBoundary constructor");
185             BoundaryType = BoundaryType.Circle;
186             IntPtr boundsHandle;
187             int ret = Interop.LocationBoundary.CreateCircleBoundary(coordinate, radius, out boundsHandle);
188             if ((LocationBoundError)ret != LocationBoundError.None)
189             {
190                 Log.Error(Globals.LogTag, "Error Creating Circular Boundary," + (LocationBoundError)ret);
191                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
192             }
193             handle = boundsHandle;
194         }
195
196         /// <summary>
197         /// Gets the coordinate of the center of a circular boundary.
198         /// </summary>
199         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
200         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
201         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
202         public Coordinate Center
203         {
204             get
205             {
206                 return GetCircleCenter();
207             }
208         }
209
210         /// <summary>
211         /// Gets the radius of a circular boundary.
212         /// </summary>
213         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
214         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
215         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
216         public double Radius
217         {
218             get
219             {
220                 return GetRadius();
221             }
222         }
223
224         private Coordinate GetCircleCenter()
225         {
226             Log.Info(Globals.LogTag, "Calling to get CoordinateItem Center");
227             Coordinate center;
228             double radius;
229             int ret = Interop.LocationBoundary.GetCircleCoordinates(handle, out center, out radius);
230             if ((LocationBoundError)ret != LocationBoundError.None)
231             {
232                 Log.Error(Globals.LogTag, "Error Get Circle Center," + (LocationBoundError)ret);
233                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
234             }
235             return center;
236         }
237
238         private double GetRadius()
239         {
240             Coordinate center;
241             double radius = 0;
242             int ret = Interop.LocationBoundary.GetCircleCoordinates(handle, out center, out radius);
243             if ((LocationBoundError)ret != LocationBoundError.None)
244             {
245                 Log.Error(Globals.LogTag, "Error Get Radius," + (LocationBoundError)ret);
246                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
247             }
248             return radius;
249         }
250     }
251
252     /// <summary>
253     /// Class representing a polygonal location boundary.
254     /// Inherits the Abstract LocationBoundary class.
255     /// </summary>
256     public class PolygonBoundary : LocationBoundary
257     {
258         /// <summary>
259         /// Constructor of the polygon boundary class.
260         /// </summary>
261         /// <param name="coordinates"> The coordinates which constitute the polgonal boundary.</param>
262         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
263         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
264         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
265         public PolygonBoundary(IList<Coordinate> coordinates)
266         {
267             Log.Info(Globals.LogTag, "Calling PolygonBoundary Constructor");
268             if (coordinates == null)
269             {
270                 Log.Error(Globals.LogTag, "coordingtes list is null");
271                 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
272             }
273
274             BoundaryType = BoundaryType.Polygon;
275             IntPtr listPointer = Marshal.AllocHGlobal(Marshal.SizeOf(coordinates[0]) * coordinates.Count);
276             IntPtr boundsHandle;
277             for (int i = 0; i < coordinates.Count; i++)
278             {
279                 Marshal.StructureToPtr(coordinates[i], listPointer + i * Marshal.SizeOf(coordinates[0]), false);
280             }
281             int ret = Interop.LocationBoundary.CreatePolygonBoundary(listPointer, coordinates.Count, out boundsHandle);
282             if ((LocationBoundError)ret != LocationBoundError.None)
283             {
284                 Log.Error(Globals.LogTag, "Error Creating Polygon Boundary," + (LocationBoundError)ret);
285                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
286             }
287             handle = boundsHandle;
288         }
289
290         /// <summary>
291         /// Gets the list of coordinates which constitute a polygonal boundary
292         /// </summary>
293         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
294         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
295         /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
296         public IList<Coordinate> Coordinates
297         {
298             get
299             {
300                 return GetCoordinates();
301             }
302         }
303
304         private IList<Coordinate> GetCoordinates()
305         {
306             Log.Info(Globals.LogTag, "Calling to get Polygon coordinates");
307             List<Coordinate> coordinateList = new List<Coordinate>();
308             Interop.LocationBoundary.PolygonCoordinatesCallback callback = (Coordinate coordinate, IntPtr userData) =>
309             {
310                 Coordinate item;
311                 item.Latitude = coordinate.Latitude;
312                 item.Longitude = coordinate.Longitude;
313                 coordinateList.Add(item);
314                 return true;
315             };
316
317             int ret = Interop.LocationBoundary.GetForEachPolygonCoordinates(handle, callback, IntPtr.Zero);
318             if ((LocationBoundError)ret != LocationBoundError.None)
319             {
320                 Log.Error(Globals.LogTag, "Error Get foreach Boundary," + (LocationBoundError)ret);
321                 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
322             }
323             return coordinateList;
324         }
325     }
326
327     /// <summary>
328     /// The structure which represents the  co-ordinates of a geographical location.
329     /// </summary>
330     [StructLayout(LayoutKind.Sequential)]
331     public struct Coordinate
332     {
333         /// <summary>
334         /// Latitude component of the co-ordinate.
335         /// Should have a value between [-90.0 ~ 90.0] (degrees).
336         /// </summary>
337         public double Latitude;
338
339         /// <summary>
340         /// Longitude component of the co-ordinate.
341         /// Should have a value between [-180.0 ~ 180.0] (degrees).
342         /// </summary>
343         public double Longitude;
344     }
345 }