public KDTree(List <GISDataPoint> dataSet) { k = 3; root = buildTree(dataSet, 0); }
public List <Neighbor> GetNearestNeighbors(GISDataPoint dataPoint, int numberOfNeighbors, KTreeNode startNode, int depth) { KTreeNode currentNode = startNode; KTreeNode skippedSubRoot; List <Neighbor> nearestNeighbors = new List <Neighbor>(); List <Neighbor> nearestNeighborsAlternate = new List <Neighbor>(); nearestNeighbors.Add(new Neighbor(currentNode.dataPoint, CalculateDistance(currentNode.dataPoint, dataPoint))); double targetDistance = CalculateDistance(dataPoint, nearestNeighbors.ElementAt(0).Point); double candidateDistance; int dimension; int k = this.k; while (currentNode.childLeft != null || currentNode.childRight != null) { dimension = depth % k; if (dataPoint.GetDimension(dimension) < currentNode.dataPoint.GetDimension(dimension)) { if (currentNode.childLeft != null) { currentNode = currentNode.childLeft; } else { currentNode = currentNode.childRight; } } else { if (currentNode.childRight != null) { currentNode = currentNode.childRight; } else { currentNode = currentNode.childLeft; } } candidateDistance = CalculateDistance(dataPoint, currentNode.dataPoint); if (candidateDistance < targetDistance || nearestNeighbors.Count < numberOfNeighbors) { nearestNeighbors.Add(new Neighbor(currentNode.dataPoint, candidateDistance)); Neighbor.Sort(nearestNeighbors, numberOfNeighbors); targetDistance = nearestNeighbors.ElementAt(nearestNeighbors.Count - 1).Distance; } depth++; } while (currentNode != startNode) { depth--; currentNode = currentNode.parent; dimension = depth % k; candidateDistance = Math.Sqrt(Math.Pow((currentNode.dataPoint.GetDimension(dimension) - dataPoint.GetDimension(dimension)), 2)); if (candidateDistance < targetDistance || nearestNeighbors.Count < numberOfNeighbors) { if (dataPoint.GetDimension(dimension) < currentNode.dataPoint.GetDimension(dimension)) { if (currentNode.childLeft != null && currentNode.childRight != null) { skippedSubRoot = currentNode.childRight; } else { continue; } } else { if (currentNode.childLeft != null && currentNode.childRight != null) { skippedSubRoot = currentNode.childLeft; } else { continue; } } nearestNeighborsAlternate = GetNearestNeighbors(dataPoint, numberOfNeighbors, skippedSubRoot, depth + 1); nearestNeighbors.AddRange(nearestNeighborsAlternate); Neighbor.Sort(nearestNeighbors, numberOfNeighbors); targetDistance = nearestNeighbors.ElementAt(nearestNeighbors.Count - 1).Distance; } } return(nearestNeighbors); }
protected override void OnBeginLoading(KTreeNode node) { base.OnBeginLoading(node); ((StoreTreeNode)node)._reloader.Visible = true; ((StoreTreeNode)node)._reloader.Animate = true; }
private static void ApplyReadOnly(KTreeNode node, bool isReadOnly) { node.ToolTip = isReadOnly ? Properties.Resources.SharedFolders_Node_Readonly_ToolTip : null; }
protected override object DoLoadChildren(KTreeNode node) { return(_folders.GetStoreFolders(User)); }
private void dialogButtons_Apply(object sender, EventArgs e) { int folderCount = 0; // Check if all fields are properly set foreach (StoreTreeNode storeNode in _userFolders.Values) { // Check totals folderCount += storeNode.CurrentShares.Count(); // Check modified folders if (storeNode.IsDirty) { foreach (SharedFolder folder in storeNode.CurrentShares) { // Check if the send-as address has been resolved (or entered) correctly if (folder.FlagSendAsOwner && string.IsNullOrWhiteSpace(folder.SendAsAddress)) { // Find the tree node KTreeNode folderNode = storeNode.FindNode(folder); if (folderNode != null) { // See if we can obtain it from a parent TryInitSendAsAddressParent(folderNode as FolderTreeNode); if (!string.IsNullOrWhiteSpace(folder.SendAsAddress)) { continue; } // If the node is already selected, explicitly warn about the send-as address // Otherwise, selecting it will pop up the warning if (folderNode.IsSelected) { TryInitSendAsAddress(); } else { FocusNode(folderNode, false); } } return; } } } } // Check total number of folders if (folderCount >= _feature.MaxFolderCount) { MessageBox.Show(ThisAddIn.Instance.Window, Properties.Resources.SharedFolders_TooManyFolders_Body, Properties.Resources.SharedFolders_TooManyFolders_Title, MessageBoxButtons.OK, MessageBoxIcon.Error ); // And don't apply anything return; } BusyText = Properties.Resources.SharedFolders_Applying_Label; KUITask.New((ctx) => { // We reuse the same busy indicationg for all calls. A count is kept to ensure it's removed. ApplyState state = new ApplyState(); foreach (StoreTreeNode storeNode in _userFolders.Values) { // Check modified folders if (storeNode.IsDirty) { ctx.AddBusy(1); ++state.folders; // Check removed shares _folders.RemoveSharesForStore(storeNode.User, storeNode.RemovedShares); // Set shares _folders.SetSharesForStore(storeNode.User, storeNode.CurrentShares, ctx.CancellationToken); } // And modified stores if (storeNode.IsWholeStoreDirty) { state.stores.Add(storeNode); } } return(state); }) .OnSuccess((ctx, state) => { // Update UI state foreach (StoreTreeNode storeNode in _userFolders.Values) { if (storeNode.IsDirty) { storeNode.ChangesApplied(); } } ctx.AddBusy(-state.folders); List <ZPushAccount> syncAdditional = new List <ZPushAccount>(); // Handle stores if (state.stores.Count > 0) { List <StoreTreeNode> add = new List <StoreTreeNode>(); // Remove any unshared store foreach (StoreTreeNode store in state.stores) { if (store.WantShare) { // Check if it must be added if (!store.IsShared) { add.Add(store); } // Update reminders for existing stores if (store.ShowReminders != store.ShowRemindersInitial) { ZPushAccount storeAccount = store.WholeStoreAccount; if (storeAccount != null) { storeAccount.ShowReminders = store.ShowReminders; syncAdditional.Add(storeAccount); // Update UI state store.ShowRemindersInitial = store.ShowReminders; WholeStoreShareChanged(store); } } continue; } else { // Remove it _feature.RemoveSharedStore(_account, store.User); store.IsShared = false; WholeStoreShareChanged(store); } } // Check for any new stores if (add.Count > 0) { bool restart = MessageBox.Show(ThisAddIn.Instance.Window, Properties.Resources.SharedFolders_WholeStoreRestart_Body, Properties.Resources.SharedFolders_WholeStoreRestart_Title, MessageBoxButtons.OKCancel, MessageBoxIcon.Information ) == DialogResult.OK; // Reset state. Also do this when restarting, to avoid warning message about unsaved changes foreach (StoreTreeNode node in state.stores) { node.WantShare = node.IsShared; } if (!restart) { return; } // Restart IRestarter restarter = ThisAddIn.Instance.Restarter(); restarter.CloseWindows = true; foreach (StoreTreeNode node in state.stores) { restarter.OpenShare(_account, node.User, node.ShowReminders); } restarter.Restart(); } // Update UI state foreach (StoreTreeNode storeNode in _userFolders.Values) { storeNode.ChangesApplied(); } CheckDirty(); } // Sync accounts foreach (ZPushAccount account in syncAdditional) { _feature.Sync(account); } if (state.folders != 0) { // Sync account _feature.Sync(_account); // Show success ShowCompletion(Properties.Resources.SharedFolders_Applying_Success); } }, true) .OnError((x) => { ErrorUtil.HandleErrorNew(typeof(FeatureSharedFolders), "Exception applying shared folders for account {0}", x, Properties.Resources.SharedFolders_Applying_Title, Properties.Resources.SharedFolders_Applying_Failure, _account.DisplayName); }) .Start(this); }
private void InitialiseTree(KUITaskContext context, Dictionary <GABUser, Dictionary <BackendId, SharedFolder> > shares) { kTreeFolders.BeginUpdate(); try { // Add public folders Dictionary <BackendId, SharedFolder> publicShares; shares.TryGetValue(GABUser.USER_PUBLIC, out publicShares); AddUserFolders(GABUser.USER_PUBLIC, null, publicShares, false); // Add shared stores foreach (ZPushAccount shared in _account.SharedAccounts) { AddUserFolders(new GABUser(shared.ShareUserName), shared, null, false); } // Add any users for which we have shared folders foreach (KeyValuePair <GABUser, Dictionary <BackendId, SharedFolder> > entry in shares.OrderBy(x => x.Key.DisplayName)) { if (GABUser.USER_PUBLIC != entry.Key) { AddUserFolders(entry.Key, null, entry.Value, false); } } } finally { kTreeFolders.EndUpdate(); } // Try to select initial node if (_initialFolder != null) { StoreTreeNode node; if (_userFolders.TryGetValue(_initialFolder.Store, out node)) { // Keep indicating busy until it's done context.AddBusy(1); node.NodesLoaded += (_) => { KTreeNode folderNode = node.FindNode(_initialFolder); if (folderNode != null) { FocusNode(folderNode, true); } context.AddBusy(-1); }; FocusNode(node, true); } SetInitialFocus(kTreeFolders); } else if (_initialAccount != null) { StoreTreeNode node; if (_userFolders.TryGetValue(new GABUser(_initialAccount.ShareUserName), out node)) { FocusNode(node, true); } } else { SetInitialFocus(gabLookup); } }