public LocationLinkObj(LocationObj LocOnSection, long LocOnRef, Geometry.GridLineSegment line) { this.LocationOnSection = LocOnSection; this.LocationOnReference = LocOnRef; lineSegment = line; lineGraphic = new RoundLineCode.RoundLine((float)line.A.X, (float)line.A.Y, (float)line.B.X, (float)line.B.Y); }
public LocationLink(LocationObj LocOne, LocationObj LocTwo) { if (LocOne == null) throw new ArgumentNullException("LocOne"); if (LocTwo == null) throw new ArgumentNullException("LocTwo"); Debug.Assert(LocOne != LocTwo); this.A = LocOne.ID < LocTwo.ID ? LocOne : LocTwo; this.B = LocOne.ID > LocTwo.ID ? LocOne : LocTwo; // lineSegment = new Geometry.GridLineSegment(A.VolumePosition, B.VolumePosition); }
private bool MapLocation(LocationObj loc) { GridVector2 VolumePosition = new GridVector2(-1, -1); //Don't bother mapping if the location was already mapped if (loc.VolumeTransformID == parent.CurrentTransformUniqueID) return true; bool mappedPosition = parent.TrySectionToVolume(loc.Position, this.Section.section, out VolumePosition); if (!mappedPosition) //Remove locations we can't map { Trace.WriteLine("AddLocation: Location #" + loc.ID.ToString() + " was unmappable.", "WebAnnotation"); return false; } loc.VolumePosition = VolumePosition; loc.VolumeTransformID = parent.CurrentTransformUniqueID; return true; }
public Location_CanvasPolyLineViewModel(LocationObj obj) : base(obj) { }
public LocationViewModel(LocationObj loc) { obj = loc; this.SectionPosition = new Point(loc.Position.X, loc.Position.Y); this.Radius = loc.Radius; }
public Location_CanvasViewModel(LocationObj location) : base(location) { }
protected void OnCreateStructure(long TypeID) { StructureTypeObj typeObj = Store.StructureTypes.GetObjectByID(TypeID); if (typeObj != null) { StructureType type = new StructureType(typeObj); System.Drawing.Point ClientPoint = _Parent.PointToClient(System.Windows.Forms.Control.MousePosition); GridVector2 WorldPos = _Parent.ScreenToWorld(ClientPoint.X, ClientPoint.Y); GridVector2 SectionPos; bool success = _Parent.TryVolumeToSection(WorldPos, _Parent.Section, out SectionPos); Debug.Assert(success); if (!success) return; StructureObj newStruct = new StructureObj(type.modelObj); LocationObj newLocation = new LocationObj(newStruct, SectionPos, WorldPos, Parent.Section.Number); Structure newStructView = new Structure(newStruct); Location_CanvasViewModel newLocationView = new Location_CanvasViewModel(newLocation); if (type.Parent == null) { Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, type, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewStructureCommand), new object[] { Parent, newStructView, newLocationView }); } else { //Enqueue two commands to resize the location and then select a parent Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, type, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(LinkStructureToParentCommand), new object[] { Parent, newStructView, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewStructureCommand), new object[] { Parent, newStructView, newLocationView }); } } else Trace.WriteLine("Could not find hotkey ID for type: " + TypeID.ToString()); }
public static void GoToLocation(LocationObj loc) { if(loc == null) return; //Adjust downsample so the location fits nicely in the view double downsample = ((loc.Radius * 2) / Viking.UI.State.ViewerForm.Width) * Global.DefaultLocationJumpDownsample; //SectionViewerForm.Show(section); Viking.UI.State.ViewerForm.GoToLocation(new Microsoft.Xna.Framework.Vector2((float)loc.Position.X, (float)loc.Position.Y), (int)loc.Z, true, downsample); //BUG: This is because the way I handle commands changed dramatically between Plantmap and Viking. I need to //set selected object to null to keep the UI from doing strange things Viking.UI.State.SelectedObject = null; }
/// <summary> /// When the user left clicks the control we create a new structure at that location /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public override void OnMouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { //Create a new structure on left click if (e.Button == MouseButtons.Left) { WebAnnotation.Objects.StructureTypeObj obj = Viking.UI.State.SelectedObject as WebAnnotation.Objects.StructureTypeObj; // Debug.Assert(obj == null, "This command should be inactive if Selected Object isn't a StructureTypeObj"); if(obj == null) return; GridVector2 WorldPos = Parent.ScreenToWorld(e.X, e.Y); //Transform from volume space to section space if we need to GridVector2 SectionPos = Parent.Section.VolumeToSection(WorldPos); StructureObj newStruct = new StructureObj(obj); LocationObj newLocation = new LocationObj(newStruct, SectionPos, WorldPos, Parent.Section.Number); if (obj.Parent == null) { StructureStore.CreateStructure(newStruct, newLocation); } else { Parent.CurrentCommand = new LinkStructureToParentCommand(Parent, newStruct, newLocation); } } else if (e.Button == MouseButtons.Right) { this.Deactivated = true; } base.OnMouseClick(sender, e); }
public OverlappedLocation(LocationLink linkObj, LocationObj location, GridCircle circle) : base(location) { link = linkObj; gridCircle = circle; }
/// <summary> /// A key is about to be added to the location store or we have retrieved a key from the /// location store and want to add it to our cache. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void AddLocation(LocationObj obj) { //Trace.WriteLine("AddLocation: " + obj.ToString(), "WebAnnotation"); // lock (LockObject) { //Add the location to our mapping if the location is on our section if (obj.Section == Section.Number) { GridVector2 VolumePosition = new GridVector2(-1, -1); try { VolumePosition = parent.SectionToVolume(new GridVector2(obj.X, obj.Y)); } catch (ArgumentException except) //Remove locations we can't map { /*PORT Concurrent Collections if (Locations.ContainsKey(obj.ID)) Locations.Remove(obj.ID); */ GridVector2 junkVal; TransformedLocationPositionDict.TryRemove(obj.ID, out junkVal); TransformedLocationQuadTree.TryRemove(obj.ID); return; } finally { obj.VolumeX = VolumePosition.X; obj.VolumeY = VolumePosition.Y; } //Add location if it hasn't been seen before bool Added = TransformedLocationPositionDict.TryAdd(obj.ID, VolumePosition); if (Added) { TransformedLocationQuadTree.TryAdd(VolumePosition, obj.ID); } else { //We had this location already, update it //Update the position, then move on if (TransformedLocationPositionDict[obj.ID] != VolumePosition) { //Remove from our data structures, update position, and then re-add RemoveLocationLinks(obj); //This is a temporary hack to deal with the ID number change when inserting values into the database TransformedLocationQuadTree.TryRemove(obj.ID); TransformedLocationPositionDict[obj.ID] = VolumePosition; TransformedLocationQuadTree.Add(VolumePosition, obj.ID); } } ConcurrentDictionary<long, LocationObj> KnownLocationsForStructure; KnownLocationsForStructure = LocationsForStructure.GetOrAdd(obj.ParentID.Value, new ConcurrentDictionary<long, LocationObj>()); KnownLocationsForStructure.TryAdd(obj.ID, obj); AddLocationLinks(obj); } else { Viking.VolumeModel.Section ReferenceSection = null; if (Section.ReferenceSectionAbove != null) { if (obj.Section == Section.ReferenceSectionAbove.Number) ReferenceSection = Section.ReferenceSectionAbove; } if (Section.ReferenceSectionBelow != null) { if (obj.Section == Section.ReferenceSectionBelow.Number) ReferenceSection = Section.ReferenceSectionBelow; } if (ReferenceSection != null) { GridVector2 VolumePosition = new GridVector2(-1, -1); try { VolumePosition = parent.SectionToVolume(new GridVector2(obj.X, obj.Y), ReferenceSection); } catch (ArgumentOutOfRangeException except) //Remove locations we can't map { GridVector2 outParam; TransformedLocationPositionDict.TryRemove(obj.ID, out outParam); TransformedRefLocationQuadTree.TryRemove(obj.ID); return; } finally { obj.VolumeX = VolumePosition.X; obj.VolumeY = VolumePosition.Y; } bool AddSuccess = TransformedLocationPositionDict.TryAdd(obj.ID, VolumePosition); TransformedRefLocationQuadTree.TryAdd(VolumePosition, obj.ID); if (AddSuccess == false) { if (TransformedLocationPositionDict[obj.ID] != VolumePosition) { TransformedLocationPositionDict[obj.ID] = VolumePosition; //This is a temporary hack to deal with the ID number change when inserting values into the database TransformedRefLocationQuadTree.TryRemove(obj.ID); TransformedRefLocationQuadTree.Add(VolumePosition, obj.ID); } } AddLocationLinks(obj); } } } if (AnnotationChanged != null) AnnotationChanged(obj, new EventArgs()); // Trace.WriteLine("End AddLocation: " + obj.ToString(), "WebAnnotation"); }
/// <summary> /// All locations which are linked get a line between them /// </summary> internal void RemoveLocationLinks(LocationObj obj) { foreach (long linkedID in obj.Links) { GridVector2 position; GridVector2 linkedPosition; bool success = TransformedLocationPositionDict.TryGetValue(obj.ID, out position); if (!success) continue; success = TransformedLocationPositionDict.TryGetValue(linkedID, out linkedPosition); if (!success) continue; GridLineSegment lineSegment = new GridLineSegment(position, linkedPosition); LocationLinkObj oldLink = null; success = LocationLinksSearch.TryRemove(lineSegment, out oldLink); if(success) { oldLink.OnAfterDelete -= LocationLinkDeletedEventHandler; } } }
/// <summary> /// All locations which are linked get a line between them /// </summary> internal void AddLocationLinks(LocationObj obj) { //Only add objects in the same section if (obj.Z != Section.Number) { return; } foreach (long linkedID in obj.Links) { GridVector2 position; GridVector2 linkedPosition; bool success = TransformedLocationPositionDict.TryGetValue(obj.ID, out position); if (!success) continue; success = TransformedLocationPositionDict.TryGetValue(linkedID, out linkedPosition); if (!success) continue; GridLineSegment lineSegment = new GridLineSegment(position, linkedPosition); LocationLinkObj locLink = new LocationLinkObj(obj, linkedID, lineSegment); locLink.OnAfterDelete += LocationLinkDeletedEventHandler; LocationLinkObj oldLink = null; success = LocationLinksSearch.TryRemove(lineSegment, out oldLink); if (oldLink != null) { oldLink.OnAfterDelete -= LocationLinkDeletedEventHandler; } success = LocationLinksSearch.TryAdd(lineSegment, locLink); } }
private long ReleaseRefLocation(LocationObj loc) { long refCount = LocationSubscriptionRefCounts.AddOrUpdate(loc.ID, 1, (id, oldValue) => oldValue - 1); if (refCount == 0) { NotifyPropertyChangedEventManager.RemoveListener(loc, this); NotifyCollectionChangedEventManager.RemoveListener(loc.Links, this); } return refCount; }
private bool AddLocationLinkToSectionSearchGrids(LocationObj AObj, LocationObj BObj, LocationLink linkView) { int minSection = AObj.Section < BObj.Section ? AObj.Section : BObj.Section; int maxSection = AObj.Section < BObj.Section ? BObj.Section : AObj.Section; GridLineSegment lineSegment = new GridLineSegment(AObj.VolumePosition, BObj.VolumePosition); bool success = false; //Add a grid line segment to each section the link intersects for (int iSection = minSection; iSection <= maxSection; iSection++) { //TODO: Check for missing sections! if (parent.Section.VolumeViewModel.SectionViewModels.ContainsKey(iSection) == false) continue; //int EstimatedLinks = Store.Locations.GetObjectsForSection(iSection).Count; //if (EstimatedLinks < 2000) int EstimatedLinks = 2500; LineSearchGrid<LocationLink> searchGrid = GetOrAddSearchGrid(iSection, EstimatedLinks); // Debug.WriteLine(iSection.ToString() + " add : " + linkView.ToString() + " " + searchGrid.Count.ToString()); //Debug.Assert(false == searchGrid.Contains(linkView)); bool sectionSuccess = searchGrid.TryAdd(lineSegment, linkView); success = success || sectionSuccess; //I had this on one line, but short-circuit logic had me beating my head against the wall for too long //Debug.Assert(success); } return success; }
/// <summary> /// Add a location to the view model. /// </summary> /// <param name="loc">Location to add</param> /// <param name="Subscribe">Subscribe to the location's change events</param> /// <param name="UpdateVolumeLocations">Return True if the volume position of the location was updated</param> private bool AddLocation(LocationObj loc, bool Subscribe, bool UpdateVolumeLocations) { if (loc.Section != Section.Number) return false; //Trace.WriteLine("AddLocation: " + obj.ToString(), "WebAnnotation"); bool FirstMapping = !loc.VolumePositionHasBeenCalculated; bool UpdatedVolumeLocation = false; GridVector2 original = loc.VolumePosition; bool mapped = MapLocation(loc); if (!mapped) return false; #if SUBMITVOLUMEPOSITION if (UpdateVolumeLocations && FirstMapping) { if (GridVector2.DistanceSquared(original, loc.VolumePosition) > 225.0) { loc.SubmitOnNextUpdate(); UpdatedVolumeLocation = true; } } #endif //Add location if it hasn't been seen before Location_CanvasViewModel locView = new Location_CanvasViewModel(loc); bool Added = Locations.TryAdd(locView.VolumePosition, locView); if (Added) { if (Subscribe) { locView.RegisterForLocationEvents(); SubscribeToLocationChangeEvents(loc); } ConcurrentDictionary<long, Location_CanvasViewModel> KnownLocationsForStructure; KnownLocationsForStructure = LocationsForStructure.GetOrAdd(loc.ParentID.Value, (key) => { return new ConcurrentDictionary<long, Location_CanvasViewModel>(); }); KnownLocationsForStructure.TryAdd(locView.ID, locView); } return UpdatedVolumeLocation; }
private void UnsubscribeToLocationChangeEvents(LocationObj loc) { NotifyPropertyChangingEventManager.RemoveListener(loc, this); NotifyPropertyChangedEventManager.RemoveListener(loc, this); }
public Location_CanvasCircleAnnotationViewModel(LocationObj location) : base(location) { }
protected void OnContinueLastTrace(GridVector2 WorldPos) { if (CreateNewLinkedLocationCommand.LastEditedLocation != null) { Location_CanvasViewModel template = CreateNewLinkedLocationCommand.LastEditedLocation; if (template.Z != this.Parent.Section.Number) { GridVector2 SectionPos; bool success = _Parent.TryVolumeToSection(WorldPos, _Parent.Section, out SectionPos); Debug.Assert(success); if (!success) return; LocationObj newLoc = new LocationObj(CreateNewLinkedLocationCommand.LastEditedLocation.Parent.modelObj, SectionPos, WorldPos, Parent.Section.Number); Location_CanvasViewModel newLocView = new Location_CanvasViewModel(newLoc); Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, template.Parent.Type, newLocView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewLinkedLocationCommand), new object[] { Parent, template, newLocView }); Viking.UI.State.SelectedObject = null; CreateNewLinkedLocationCommand.LastEditedLocation = null; } } }
/// <summary> /// When the user left clicks the control we create a new structure at that location /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { //Create a new structure on left click if (e.Button == MouseButtons.Left) { // Debug.Assert(obj == null, "This command should be inactive if Selected Object isn't a StructureTypeObj"); if (Type == null) return; GridVector2 WorldPos = Parent.ScreenToWorld(e.X, e.Y); //Transform from volume space to section space if we need to GridVector2 SectionPos; bool Transformed= Parent.TryVolumeToSection(WorldPos, Parent.Section, out SectionPos); if (!Transformed) { this.Deactivated = true; base.OnMouseClick(sender, e); } StructureObj newStruct = new StructureObj(Type.modelObj); LocationObj newLocation = new LocationObj(newStruct, SectionPos, WorldPos, Parent.Section.Number); Structure newStructView = new Structure(newStruct); Location_CanvasViewModel newLocationView = new Location_CanvasViewModel(newLocation); if (Type.Parent == null) { Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, Type, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewStructureCommand), new object[] { Parent, newStructView, newLocationView }); } else { //Enqueue two commands to resize the location and then select a parent Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, Type, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(LinkStructureToParentCommand), new object[] { Parent, newStructView, newLocationView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewStructureCommand), new object[] { Parent, newStructView, newLocationView }); } Execute(); } else if (e.Button == MouseButtons.Right) { this.Deactivated = true; } base.OnMouseClick(sender, e); }
protected override void OnMouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { //If we clicked a location from another section then create a new linked section if (selected.Section != this.Parent.Section.Number) { Debug.Assert(selected != null); GridVector2 WorldPos = Parent.ScreenToWorld(e.X, e.Y); //Transform from volume space to section space if we can GridVector2 SectionPos; try { SectionPos = Parent.VolumeToSection(WorldPos); } catch (ArgumentOutOfRangeException ) { Trace.WriteLine("Could not map world point OnMouseUp: " + WorldPos.ToString(), "Command"); return; } LocationObj newLoc = new LocationObj(selected.Parent.modelObj, SectionPos, WorldPos, Parent.Section.Number); Location_CanvasViewModel newLocView = new Location_CanvasViewModel(newLoc); Viking.UI.Commands.Command.EnqueueCommand(typeof(ResizeLocationCommand), new object[] { Parent, selected.Parent.Type, newLocView }); Viking.UI.Commands.Command.EnqueueCommand(typeof(CreateNewLinkedLocationCommand), new object[] { Parent, selected, newLocView }); Viking.UI.State.SelectedObject = null; this.Execute(); } else { //If we've been dragging a location on the same section then relocate the section GridVector2 WorldPos = Parent.ScreenToWorld(e.X, e.Y); //Transform from volume space to section space if we need to GridVector2 SectionPos; try { SectionPos = Parent.VolumeToSection(WorldPos); } catch (ArgumentOutOfRangeException ) { Trace.WriteLine("Could not map world point OnMouseUp: " + WorldPos.ToString(), "Command"); return; } selected.SectionPosition = SectionPos; //Send changes to DB Store.Locations.Save(); this.Deactivated = true; } } else if (e.Button != MouseButtons.Right) { //Any other button other than the right button cancels the command this.Deactivated = true; } base.OnMouseUp(sender, e); }
/// <summary> /// Convinience method to save a Location Object. /// Important note: DO NOT CALL THIS IN A LOOP! /// </summary> /// <param name="LocationObj"></param> /// <remarks> /// Important note: DO NOT CALL THIS IN A LOOP! /// This method simply instantiates a LocationDBMapper and calls the save method /// </remarks> public static void saveLocation(params Location[] LocationObj) { LocationDBMapper dbm = new LocationDBMapper(); dbm.saveList(LocationObj.ToList()); }