⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 integerclassifier.cs

📁 实现SHP
💻 CS
字号:
///GeoCon, free tool to create gml & svg from gis files. 
///Copyright(C) 2005 Amri Rosyada
///Distributed under GNU-LGPL, see a copy of the license in root directory
using System;
using System.Collections;

using GeoCon.Data;
namespace GeoCon.Classification
{
	/// <summary>
	/// Summary description for IntegerClassifier.
	/// </summary>
	[Serializable]
	public class IntegerClassifier : Classifier
	{
		#region constructors
		public IntegerClassifier(): base(){}
		public IntegerClassifier(ClassificationInfo cinfo) : base(cinfo){}
		public IntegerClassifier(ClassificationInfo cinfo,ArrayList idxs) : base (cinfo,idxs) {}
		#endregion

		#region utilities
		private static int getMinInclusiveIndex(object[] objs,int val)
		{
			if((int)objs[0]>val) return -1;
			if((int)objs[objs.Length-1]<=val) return objs.Length-1;
			for(int i=0;i<objs.Length;i++) if((int)objs[i]>=val) return i;
			return -1;
		}
		private static int getMaxInclusiveIndex(object[] objs,int val)
		{
			if((int)objs[0]>val) return -1;
			if((int)objs[objs.Length-1]<=val) return objs.Length-1;
			for(int i=objs.Length-1;i>-1;i--) if((int)objs[i]<=val) return i;
			return -1;
		}
		private int GetUniqueCount(object[] objs)
		{
			int uniqueCount=1;
			for(int i=1;i<objs.Length;i++) if((int)objs[i]!=(int)objs[i-1]) uniqueCount++;
			return uniqueCount;
		}
		#endregion

		#region equal classification
		public BinCollection ClassifyEqual() 
		{
			int[] idxs=new int[0];
			object[] objs=this.GetSortedNonNullValues(out idxs);
			BinCollection bins = new BinCollection(Setup);
			if(objs.Length==0) return bins;
			if(Setup.BinsCount>=GetUniqueCount(objs)) return ClassifyUnique();

			int rng = (int)objs[objs.Length-1] - (int)objs[0] + 1; //why +1?
			int interval=(int)(Math.Floor((double)rng/(double)(Setup.BinsCount)));
			int remains = rng-interval*Setup.BinsCount;
			Remainder rem=new Remainder(); //remains should be distributed evenly accross bins median
			int[] rempat = rem.GetRemainderPattern(remains,Setup.BinsCount); 
			int vLow = (int)objs[0];
			for(int b=0;b<Setup.BinsCount;b++)
			{
				int vHigh = vLow+interval+rempat[b]-1; //-1 because it's Max Inclusive
				bins.Add(new IntegerBin(vLow,vHigh));
				int mini = getMinInclusiveIndex(objs,vLow);
				int maxi = getMaxInclusiveIndex(objs,vHigh);
				for(int i=mini;i<maxi+1;i++) bins[bins.Count-1].ContentsIndex.Add(idxs[i]);
				vLow=vHigh+1;
			}		

			FillNullBin(bins.NullBin,idxs);
			objs=null;
			idxs=null;
			rem=null;
			rempat=null;

			return bins;
		}
		#endregion

		#region quantile classification
		public BinCollection ClassifyQuantile()
		{
			int[] idxs=new int[0];
			object[] objs=this.GetSortedNonNullValues(out idxs);
			BinCollection bins = new BinCollection(Setup);
			if(objs.Length==0) return bins;
			if(Setup.BinsCount>=GetUniqueCount(objs)) return ClassifyUnique();

			int dcount = objs.Length;
			int interval=(int)(Math.Floor((double)dcount/(double)Setup.BinsCount));
			int remains = dcount-interval*Setup.BinsCount;
			Remainder rem=new Remainder(); //remains should be distributed evenly accross the bins median
			int[] rempat = rem.GetRemainderPattern(remains,Setup.BinsCount); 

			int nLow=0;
			for(int b=0;b<Setup.BinsCount;b++)
			{
				int vLow  = (int)objs[nLow];
				int nHigh = nLow+interval+rempat[b]-1;
				if(nHigh>=objs.Length) nHigh=objs.Length-1;
				int vHigh = (int)objs[nHigh];
				bins.Add(new IntegerBin(vLow,vHigh));
				int mini=Array.IndexOf(objs,vLow);
				int maxi=Array.LastIndexOf(objs,vHigh);
				for(int i=mini;i<maxi+1;i++) bins[bins.Count-1].ContentsIndex.Add(idxs[i]);
				nLow=maxi+1;
			}

			FillNullBin(bins.NullBin,idxs);
			objs=null;
			idxs=null;
			rem=null;
			rempat=null;
			
			return bins;
		}

		#endregion

		#region natural classification
		public BinCollection ClassifyNatural()
		{
			int[] idxs=new int[0];
			object[] objs=this.GetSortedNonNullValues(out idxs);
			BinCollection bins = new BinCollection(Setup);
			if(objs.Length==0) return bins;
			if(Setup.BinsCount>=GetUniqueCount(objs)) return ClassifyUnique();

			int[] kclass= getNaturalBreaks(objs,Setup.BinsCount);
			int mini=0;
			for(int b=1;b<Setup.BinsCount+1;b++)
			{
				int index=(b==Setup.BinsCount)? kclass[Setup.BinsCount - 1] : kclass[b - 1];
				int maxi = index;
				if(mini<0) mini=0;
				if(mini>=objs.Length) mini=objs.Length-1;
				int vLow = (int)objs[mini];
				if(mini>maxi || maxi<0 || maxi>=objs.Length) maxi=mini;
				int vHigh = (int)objs[maxi];
				bins.Add(new IntegerBin(vLow,vHigh));
				for(int i=mini;i<maxi+1;i++) bins[bins.Count-1].ContentsIndex.Add(idxs[i]);
				vLow=vHigh;
				mini=maxi+1;
			}

			FillNullBin(bins.NullBin,idxs);

			kclass=null;
			idxs=null;
			objs=null;

			return bins;
		}

		/// <summary>
		/// Gets Jenks break indexes.  This algorithm is taken from GeoTools project (www.geotools.org)
		/// </summary>
		/// <param name="values">data values in which to find breaks</param>
		/// <param name="count">number of breaks desired</param>
		/// <returns>Index of breaks inside data values</returns>
		private static int[] getNaturalBreaks(object[] values,int count)
		{
			int numdata = values.Length;
			int[] st = new int[numdata];
			int[][] mat1 = new int[numdata + 1][];
			int[][] mat2 = new int[numdata + 1][];
			for(int i=0;i<numdata+1;i++)
			{
				mat1[i]=new int[count+1];
				mat2[i]=new int[count+1];
			}
			for (int i = 1; i<count+1; i++) 
			{
				mat1[1][i] = 1;
				mat2[1][i] = 0;
				for (int j = 2; j<=numdata; j++) mat2[j][i] = int.MaxValue;
			}
			int v = 0;
			for (int l = 2; l < numdata+1; l++) 
			{
				int s1 = 0;
				int s2 = 0;
				int w = 0;
				for (int m = 1; m < l+1; m++) 
				{
					int i3 = l - m + 1;
					int val = (int)values[i3-1];
					s2 += val * val;
					s1 += val;
					w++;
					v = s2 - (s1 * s1) / w;
					int i4 = i3 - 1;
					if (i4 != 0) 
					{
						for (int j = 2; j < count+1; j++) 
						{
							if (mat2[l][j] >= (v + mat2[i4][j - 1])) 
							{
								mat1[l][j] = i3;
								mat2[l][j] = v + mat2[i4][j - 1];
							}
						}
					}
				}
				mat1[l][1] = 1;
				mat2[l][1] = v;
			}

			int k = numdata; 
			int[] kclass = new int[count];
			kclass[count - 1] = values.Length - 1;
			for (int j = count; j > 1; j--) 
			{
				int id =  (int) (mat1[k][j]) - 2;
				kclass[j - 2] = id;
				k = (int) mat1[k][j] - 1;
			}

			st=null;
			mat1=null;
			mat2=null;
			return kclass;
		}
		#endregion
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -