public void Update(XExtent _Extent, Rectangle _Rectangle) { //CurrentMapExtent = _Extent; //MapWindowSize = _Rectangle; //MapMinX = CurrentMapExtent.GetMinX(); //MapMinY = CurrentMapExtent.GetMinY(); //WinW = MapWindowSize.Width; //WinH = MapWindowSize.Height; //MapW = CurrentMapExtent.GetWidth(); //MapH = CurrentMapExtent.GetHeight(); //ScaleX = MapW / WinW; //ScaleY = MapH / WinH; //ScaleX = Math.Max(ScaleX, ScaleY); //ScaleY = ScaleX; CurrentMapExtent = _Extent; MapWindowSize = _Rectangle; WinW = MapWindowSize.Width; WinH = MapWindowSize.Height; ScaleX = CurrentMapExtent.GetWidth() / WinW; ScaleY = CurrentMapExtent.GetHeight() / WinH; ScaleX = Math.Max(ScaleX, ScaleY); ScaleY = ScaleX; MapW = MapWindowSize.Width * ScaleX; MapH = MapWindowSize.Height * ScaleY; XVertex center = CurrentMapExtent.GetCenter(); MapMinX = center.X - MapW / 2; MapMinY = center.Y - MapH / 2; CurrentMapExtent = new XExtent(new XVertex(MapMinX, MapMinY), new XVertex(MapMinX + MapW, MapMinY + MapH)); }
static double Dot3Product(XVertex A, XVertex B, XVertex C) { XVertex AB = new XVertex(B.X - A.X, B.Y - A.Y);//矢量也可以通过vertex来记录 XVertex BC = new XVertex(C.X - B.X, C.Y - B.Y); return(AB.X * BC.X + AB.Y * BC.Y); }
internal double ToScreenDistance(XVertex v, XVertex centroid) { Point p1 = ToScreenPoint(v); Point p2 = ToScreenPoint(centroid); return(Math.Sqrt((double)((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)))); }
static double Cross3Product(XVertex A, XVertex B, XVertex C) { XVertex AB = new XVertex(B.X - A.X, B.Y - A.Y);//矢量也可以通过vertex来记录 XVertex AC = new XVertex(C.X - A.X, C.Y - A.Y); return(VectorProduct(AB, AC)); }
internal bool Incude(XVertex vertex) { int count = 0; for (int i = 0; i < AllVertexes.Count; i++) { //满足点在线上直接返回false if (AllVertexes[i].IsSame(vertex)) { return(false); } //由序号i和下一个点构成一条线段 可以算出下一个点next的公式 int next = (i + 1) % AllVertexes.Count; //确定线段的坐标极值 double minx = Math.Min(AllVertexes[i].X, AllVertexes[next].X); double miny = Math.Min(AllVertexes[i].Y, AllVertexes[next].Y); double maxx = Math.Max(AllVertexes[i].X, AllVertexes[next].X); double maxy = Math.Max(AllVertexes[i].Y, AllVertexes[next].Y); //如果线段平行于射线 if (miny == maxy) { //满足点在线上直接返回false if (miny == vertex.Y && vertex.X >= minx && vertex.X <= maxx) { return(false); } //满足射线与线段平行无焦点且不再线段上 else { continue; } } //点和线段都在坐标极值之外则不可能有交点 if (vertex.X > maxx || vertex.Y > maxy || vertex.Y < miny) { continue; } //计算交点横坐标 纵坐标显然就为y double x0 = AllVertexes[i].X + (vertex.Y - AllVertexes[i].Y) * (AllVertexes[next].X - AllVertexes[i].X) / (AllVertexes[next].Y - AllVertexes[i].Y); //交点在射线反方向按照没有交点计算 if (x0 < vertex.X) { continue; } //交点是vertex且在线段上,按照不包括处理(前面已经判断,但是此处仍要排除此种情况) if (x0 == vertex.X) { return(false); } //射线穿过的下断点不计数 if (vertex.Y == miny) { continue; } //其他情况交点数+1 count++; } return(count % 2 != 0); }
private void FormXGIS_MouseClick(object sender, MouseEventArgs e) { if (layer.FeatureCount() == 0) { return; } XVertex onevertex = view.ToMapVertex(e.Location); double mindistance = Double.MaxValue; int findid = -1; int index = 0; foreach (XFeature feature in layer.Features) { double distance = feature.Distance(onevertex); if (distance < mindistance) { mindistance = distance; findid = index; } index++; } int ScreenDistance = view.ToScreenDistance(mindistance); if (ScreenDistance < 5) { MessageBox.Show("找到的Feature的序号是" + findid); } }
public XExtent(XVertex _oneCorner, XVertex _anotherCorner) { UpRight = new XVertex(Math.Max(_anotherCorner.X, _oneCorner.X), Math.Max(_anotherCorner.Y, _oneCorner.Y)); BottomLeft = new XVertex(Math.Min(_anotherCorner.X, _oneCorner.X), Math.Min(_anotherCorner.Y, _oneCorner.Y)); }
internal void UpdateCenter(XVertex _NewCenter) { double width = GetWidth(); double height = GetHeight(); UpRight = new XVertex(_NewCenter.X + width / 2, _NewCenter.Y + height / 2); BottomLeft = new XVertex(_NewCenter.X - width / 2, _NewCenter.Y - height / 2); }
public void Draw(Graphics _Graphics, XView _View, XVertex _Location, int _Index) { Point screenPoint = _View.ToScreenPoint(_Location); _Graphics.DrawString(GetValue(_Index).ToString(), new Font("宋体", 20), new SolidBrush(Color.Green), screenPoint); }
private void FormXGIS_MouseUp(object sender, MouseEventArgs e) { //没有打开任何图层 if (layer == null) { return; } //未发生变化 if (e.Location.X == MouseDownLocation.X && e.Location.Y == MouseDownLocation.Y) { if (MouseSelect) { layer.SelectByClick(e.Location, view); UpdateMap(); } } else { XVertex v1 = view.ToMapVertex(MouseDownLocation); XVertex v2 = view.ToMapVertex(e.Location); //如果是拉框放大 if (MouseSelect) { XExtent extent = new XExtent(v1, v2); //if (Control.ModifierKeys == Keys.Control) //{ // layer.PlusSelectByExtent(extent); //} //else //{ // layer.SelectByExtent(extent, Control.ModifierKeys == Keys.Shift, // Control.ModifierKeys == Keys.Control); //} if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift && (Control.ModifierKeys & Keys.Control) == Keys.Control) { layer.SelectByExtent(extent, true, true); } else { layer.SelectByExtent(extent, Control.ModifierKeys == Keys.Shift, Control.ModifierKeys == Keys.Control); } } else if (MouseZoomIn) { XExtent extent = new XExtent(v1, v2); view.UpdateExtent(extent); } else if (MousePan) { view.OffsetCenter(v1, v2); } UpdateMap(); } MouseSelect = MouseZoomIn = MousePan = false; }
internal int ToScreenDistance(double _MapDistance) { XVertex v1 = new XVertex(MapMinX, MapMinY); XVertex v2 = new XVertex(MapMinX + _MapDistance, MapMinY); Point p1 = ToScreenPoint(v1); Point p2 = ToScreenPoint(v2); return((int)Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y))); }
internal void OffsetCenter(XVertex vFrom, XVertex vTo) { Point pFrom = ToScreenPoint(vFrom); Point pTo = ToScreenPoint(vTo); Point newCenterPoint = new Point(MapWindowSize.Width / 2 - pTo.X + pFrom.X, MapWindowSize.Height / 2 - pTo.Y + pFrom.Y); XVertex newCenter = ToMapVertex(newCenterPoint); CurrentMapExtent.UpdateCenter(newCenter); Update(CurrentMapExtent, MapWindowSize); }
internal override double Distance(XVertex onevertex) { double distance = Double.MaxValue; for (int i = 0; i < AllVertexes.Count - 1; i++) { distance = Math.Min(XTools.PointToSegment (AllVertexes[i], AllVertexes[i + 1], onevertex), distance); } return(distance); }
public Point ToScreenPoint(XVertex _Location) { if (FormXGIS.IsMecator) { double ScreenX = XTools.GetMecatorWidth(_Location.X, MapMinX) / ScaleX; double ScreenY = WinH - XTools.GetMecatorHeight(_Location.Y, MapMinY) / ScaleY; return(new Point((int)ScreenX, (int)ScreenY)); } else { double ScreenX = (_Location.X - MapMinX) / ScaleX; double ScreenY = WinH - (_Location.Y - MapMinY) / ScaleY; return(new Point((int)ScreenX, (int)ScreenY)); } }
internal static double PointToSegment(XVertex A, XVertex B, XVertex C) { double dot1 = Dot3Product(A, B, C); if (dot1 > 0) { return(B.Distance(C)); } double dot2 = Dot3Product(B, A, C); if (dot2 > 0) { return(A.Distance(C)); } double dist = Cross3Product(A, B, C) / A.Distance(B); return(Math.Abs(dist)); }
private void FormXGIS_MouseUp(object sender, MouseEventArgs e) { //没有打开任何图层 if (layer == null) { return; } //未发生变化 if (e.Location.X == MouseDownLocation.X && e.Location.Y == MouseDownLocation.Y) { if (MouseSelect) { layer.selectByClick(e.Location, view); UpdateMap(); } } else//框选 { XVertex v1 = view.ToMapVertex(MouseDownLocation); XVertex v2 = view.ToMapVertex(e.Location); if (MouseSelect) { XExtent extent = new XExtent(v1, v2); layer.SelectByExtent(extent); } else if (MouseZoomIn) { XExtent extent = new XExtent(v1, v2); view.UpdateExtent(extent); } else if (MousePan)//如果是平移地图 { view.OffsetCenter(v1, v2); } else if (MouseInterSelect) { XExtent extent = new XExtent(v1, v2); layer.SelectByInterExtent(extent); } UpdateMap(); } MouseSelect = MousePan = MouseZoomIn = MouseInterSelect = false; }
public XExtent(XVertex _BottomLeft, XVertex _UpRight) { BottomLeft = _BottomLeft; UpRight = _UpRight; }
internal void SelectByClick(Point location, XView view) { XVertex v = view.ToMapVertex(location); foreach (XFeature feature in Features) { feature.Selected = false; } if (ShapeType == SHAPETYPE.point) { Double distance = Double.MaxValue; int id = -1; for (int i = 0; i < Features.Count; i++) { XPointSpatial point = (XPointSpatial)(Features[i].Spatial); double dist = point.Distance(v); if (dist < distance) { distance = dist; id = i; } } double scd = view.ToScreenDistance(v, Features[id].Spatial.Centroid);//转为屏幕距离 if (scd <= 5) { Features[id].Selected = true; } else { Console.WriteLine("屏幕距离为" + scd + ",选择无效!!"); } } else if (ShapeType == SHAPETYPE.line) { Double distance = Double.MaxValue; int id = -1; for (int i = 0; i < Features.Count; i++) { XLineSpatial line = (XLineSpatial)(Features[i].Spatial); double dist = line.Distance(v); if (dist < distance) { distance = dist; id = i; } } double scd = view.ToScreenDistance(distance);//转为屏幕距离 if (scd <= 5) { Features[id].Selected = true; } else { Console.WriteLine("屏幕距离为" + scd + ",选择无效!!"); } } else if (ShapeType == SHAPETYPE.polygon) { for (int i = 0; i < Features.Count; i++) { XPolygonSpatial polygon = (XPolygonSpatial)(Features[i].Spatial); if (polygon.Incude(v)) { Features[i].Selected = true; } } } }
internal bool IsSame(XVertex vertex) { return(X == vertex.X && Y == vertex.Y); }
internal override double Distance(XVertex onevertex) { throw new NotImplementedException(); }
public static double VectorProduct(XVertex v1, XVertex v2) { return(v1.X * v2.Y - v1.Y * v2.X); }
internal override double Distance(XVertex onevertex) { return(Centroid.Distance(onevertex)); }
public XPointSpatial(XVertex _Location) { Centroid = _Location; Extent = new XExtent(_Location, _Location); }
internal double Distance(XVertex _AnotherVertex) { return(Math.Sqrt((X - _AnotherVertex.X) * (X - _AnotherVertex.X) + (Y - _AnotherVertex.Y) * (Y - _AnotherVertex.Y))); }
internal void CopyFrom(XVertex v) { X = v.X; Y = v.Y; }
internal double Distance(XVertex onevertex) { return(Spatial.Distance(onevertex)); }
internal abstract double Distance(XVertex onevertex);
private void FormXGIS_MouseMove(object sender, MouseEventArgs e) { XVertex v = view.ToMapVertex(e.Location); toolStripStatusLabel2mouselocation.Text = "mouse pointer@" + v.X.ToString() + "|" + v.Y.ToString(); }