1 /**********************************************************
2  * Version $Id: GSPoints_Pattern_Analysis.cpp 1921 2014-01-09 10:24:11Z oconrad $
3  *********************************************************/
4 
5 ///////////////////////////////////////////////////////////
6 //                                                       //
7 //                         SAGA                          //
8 //                                                       //
9 //      System for Automated Geoscientific Analyses      //
10 //                                                       //
11 //                     Tool Library                      //
12 //                   statistics_points                   //
13 //                                                       //
14 //-------------------------------------------------------//
15 //                                                       //
16 //              GSPoints_Pattern_Analysis.cpp            //
17 //                                                       //
18 //                 Copyright (C) 2010 by                 //
19 //                      Olaf Conrad                      //
20 //                                                       //
21 //-------------------------------------------------------//
22 //                                                       //
23 // This file is part of 'SAGA - System for Automated     //
24 // Geoscientific Analyses'. SAGA is free software; you   //
25 // can redistribute it and/or modify it under the terms  //
26 // of the GNU General Public License as published by the //
27 // Free Software Foundation, either version 2 of the     //
28 // License, or (at your option) any later version.       //
29 //                                                       //
30 // SAGA is distributed in the hope that it will be       //
31 // useful, but WITHOUT ANY WARRANTY; without even the    //
32 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
33 // PARTICULAR PURPOSE. See the GNU General Public        //
34 // License for more details.                             //
35 //                                                       //
36 // You should have received a copy of the GNU General    //
37 // Public License along with this program; if not, see   //
38 // <http://www.gnu.org/licenses/>.                       //
39 //                                                       //
40 //-------------------------------------------------------//
41 //                                                       //
42 //    e-mail:     oconrad@saga-gis.org                   //
43 //                                                       //
44 //    contact:    Olaf Conrad                            //
45 //                Institute of Geography                 //
46 //                University of Hamburg                  //
47 //                Germany                                //
48 //                                                       //
49 ///////////////////////////////////////////////////////////
50 
51 //---------------------------------------------------------
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
61 #include "GSPoints_Pattern_Analysis.h"
62 
63 
64 ///////////////////////////////////////////////////////////
65 //														 //
66 //														 //
67 //														 //
68 ///////////////////////////////////////////////////////////
69 
70 //---------------------------------------------------------
CGSPoints_Pattern_Analysis(void)71 CGSPoints_Pattern_Analysis::CGSPoints_Pattern_Analysis(void)
72 {
73 	//-----------------------------------------------------
74 	Set_Name		(_TL("Spatial Point Pattern Analysis"));
75 
76 	Set_Author		("O.Conrad (c) 2010");
77 
78 	Set_Description(
79 		_TL("Basic measures for spatial point patterns.")
80 	);
81 
82 	//-----------------------------------------------------
83 	Parameters.Add_Shapes("",
84 		"POINTS"	, _TL("Points"),
85 		_TL(""),
86 		PARAMETER_INPUT, SHAPE_TYPE_Point
87 	);
88 
89 	Parameters.Add_Table_Field("POINTS",
90 		"WEIGHT"	, _TL("Weight"),
91 		_TL(""),
92 		true
93 	);
94 
95 	Parameters.Add_Shapes("",
96 		"CENTRE"	, _TL("Mean Centre"),
97 		_TL(""),
98 		PARAMETER_OUTPUT, SHAPE_TYPE_Point
99 	);
100 
101 	Parameters.Add_Shapes("",
102 		"STDDIST"	, _TL("Standard Distance"),
103 		_TL(""),
104 		PARAMETER_OUTPUT, SHAPE_TYPE_Polygon
105 	);
106 
107 	Parameters.Add_Double("STDDIST",
108 		"STEP"		, _TL("Vertex Distance [Degree]"),
109 		_TL(""),
110 		5.0, 0.1, true, 20.0, true
111 	);
112 
113 	Parameters.Add_Shapes("",
114 		"BBOX"		, _TL("Bounding Box"),
115 		_TL(""),
116 		PARAMETER_OUTPUT, SHAPE_TYPE_Polygon
117 	);
118 }
119 
120 
121 ///////////////////////////////////////////////////////////
122 //														 //
123 ///////////////////////////////////////////////////////////
124 
125 //---------------------------------------------------------
On_Execute(void)126 bool CGSPoints_Pattern_Analysis::On_Execute(void)
127 {
128 	CSG_Shapes	*pPoints	= Parameters("POINTS")->asShapes();
129 
130 	if( pPoints->Get_Count() <= 1 )
131 	{
132 		Error_Set(_TL("not enough points to perform pattern analysis"));
133 
134 		return( false );
135 	}
136 
137 	int	iPoint, Weight	= Parameters("WEIGHT")->asInt();
138 
139 	CSG_Simple_Statistics	X, Y, D;
140 
141 	//-----------------------------------------------------
142 	for(iPoint=0; iPoint<pPoints->Get_Count() && Set_Progress(iPoint, pPoints->Get_Count()); iPoint++)
143 	{
144 		TSG_Point	p	= pPoints->Get_Shape(iPoint)->Get_Point(0);
145 
146 		double	w	= Weight < 0 ? 1.0 : pPoints->Get_Shape(iPoint)->asDouble(Weight);
147 
148 		X.Add_Value(p.x, w);
149 		Y.Add_Value(p.y, w);
150 	}
151 
152 	if( X.Get_Range() == 0.0 && Y.Get_Range() == 0.0 )
153 	{
154 		Error_Set(_TL("no variation in point pattern"));
155 
156 		return( false );
157 	}
158 
159 	//-----------------------------------------------------
160 	double	StdDist	= 0.0;
161 
162 	for(iPoint=0; iPoint<pPoints->Get_Count() && Set_Progress(iPoint, pPoints->Get_Count()); iPoint++)
163 	{
164 		TSG_Point	p	= pPoints->Get_Shape(iPoint)->Get_Point(0);
165 
166 		double	w	= Weight < 0 ? 1.0 : pPoints->Get_Shape(iPoint)->asDouble(Weight);
167 
168 		D.Add_Value(SG_Get_Distance(X.Get_Mean(), Y.Get_Mean(), p.x, p.y), w);
169 
170 		StdDist	+= w * (SG_Get_Square(p.x - X.Get_Mean()) + SG_Get_Square(p.y - Y.Get_Mean()));
171 	}
172 
173 	if( D.Get_Weights() == 0.0 )
174 	{
175 		Error_Set(_TL("number of valid points or sum of weights equals zero"));
176 
177 		return( false );
178 	}
179 
180 	StdDist	= sqrt(StdDist / D.Get_Weights());
181 
182 	//-----------------------------------------------------
183 	CSG_Shapes	*pShapes;	CSG_Shape	*pShape;
184 
185 	pShapes	= Parameters("CENTRE")->asShapes();
186 
187 	pShapes	->Create(SHAPE_TYPE_Point, CSG_String::Format("%s [%s]", pPoints->Get_Name(), _TL("Centre")));
188 	pShapes	->Add_Field("X_CENTRE", SG_DATATYPE_Double);
189 	pShapes	->Add_Field("Y_CENTRE", SG_DATATYPE_Double);
190 	pShapes	->Add_Field("N_POINTS", SG_DATATYPE_Double);
191 	pShapes	->Add_Field("STDDIST" , SG_DATATYPE_Double);
192 	pShapes	->Add_Field("MEANDIST", SG_DATATYPE_Double);
193 
194 	pShape	= pShapes->Add_Shape();
195 
196 	pShape	->Set_Value(0, X.Get_Mean  ());
197 	pShape	->Set_Value(1, Y.Get_Mean  ());
198 	pShape	->Set_Value(2, D.Get_Count ());
199 	pShape	->Set_Value(3, StdDist       );
200 	pShape	->Set_Value(4, D.Get_StdDev());
201 
202 	pShape	->Add_Point(X.Get_Mean(), Y.Get_Mean());
203 
204 	//-----------------------------------------------------
205 	pShapes	= Parameters("STDDIST")->asShapes();
206 
207 	pShapes	->Create(SHAPE_TYPE_Polygon, CSG_String::Format("%s [%s]", pPoints->Get_Name(), _TL("Standard Distance")));
208 	pShapes	->Add_Field("X_CENTRE", SG_DATATYPE_Double);
209 	pShapes	->Add_Field("Y_CENTRE", SG_DATATYPE_Double);
210 	pShapes	->Add_Field("N_POINTS", SG_DATATYPE_Double);
211 	pShapes	->Add_Field("STDDIST" , SG_DATATYPE_Double);
212 
213 	pShape	= pShapes->Add_Shape();
214 
215 	pShape	->Set_Value(0, X.Get_Mean ());
216 	pShape	->Set_Value(1, Y.Get_Mean ());
217 	pShape	->Set_Value(2, X.Get_Count());
218 	pShape	->Set_Value(3, StdDist      );
219 
220 	double	dTheta	= Parameters("STEP")->asDouble() * M_DEG_TO_RAD;
221 
222 	for(double Theta=0.0; Theta<=M_PI_360; Theta+=dTheta)
223 	{
224 		pShape->Add_Point(
225 			X.Get_Mean() + StdDist * cos(Theta),
226 			Y.Get_Mean() + StdDist * sin(Theta)
227 		);
228 	}
229 
230 	//-----------------------------------------------------
231 	pShapes	= Parameters("BBOX")->asShapes();
232 
233 	pShapes	->Create(SHAPE_TYPE_Polygon, CSG_String::Format("%s [%s]", pPoints->Get_Name(), _TL("Bounding Box")));
234 
235 	pShapes	->Add_Field("XMIN", SG_DATATYPE_Double);
236 	pShapes	->Add_Field("XMAX", SG_DATATYPE_Double);
237 	pShapes	->Add_Field("YMIN", SG_DATATYPE_Double);
238 	pShapes	->Add_Field("YMAX", SG_DATATYPE_Double);
239 
240 	pShape	= pShapes->Add_Shape();
241 
242 	pShape	->Set_Value(0, X.Get_Minimum());
243 	pShape	->Set_Value(1, X.Get_Maximum());
244 	pShape	->Set_Value(2, Y.Get_Minimum());
245 	pShape	->Set_Value(3, Y.Get_Maximum());
246 
247 	pShape	->Add_Point(X.Get_Minimum(), Y.Get_Minimum());
248 	pShape	->Add_Point(X.Get_Minimum(), Y.Get_Maximum());
249 	pShape	->Add_Point(X.Get_Maximum(), Y.Get_Maximum());
250 	pShape	->Add_Point(X.Get_Maximum(), Y.Get_Minimum());
251 
252 	//-----------------------------------------------------
253 	return( true );
254 }
255 
256 
257 ///////////////////////////////////////////////////////////
258 //														 //
259 //														 //
260 //														 //
261 ///////////////////////////////////////////////////////////
262 
263 //---------------------------------------------------------
264