public Point ToScreenPoint(GISVertex onevertex)//地图点到屏幕点转换 { double ScreenX = (onevertex.x - MapMinX) / ScaleX; double ScreenY = WinH - (onevertex.y - MapMinY) / ScaleY; return(new Point((int)ScreenX, (int)ScreenY)); }
//定义两个矢量运算 点积和叉积 static double Dot3Product(GISVertex A, GISVertex B, GISVertex C) { GISVertex AB = new GISVertex(B.x - A.x, B.y - A.y);//矢量也可以通过vertex来记录 GISVertex BC = new GISVertex(C.x - B.x, C.y - B.y); return(AB.x * BC.x + AB.y * BC.y); }
static double Cross3Product(GISVertex A, GISVertex B, GISVertex C) { GISVertex AB = new GISVertex(B.x - A.x, B.y - A.y);//矢量也可以通过vertex来记录 GISVertex AC = new GISVertex(C.x - A.x, C.y - A.y); return(VectorProduct(AB, AC)); }
public void draw(Graphics graphics, GISView view, GISVertex location, int index) { Point screenpoint = view.ToScreenPoint(location);//转换坐标到屏幕点 graphics.DrawString(values[index].ToString(), new Font("宋体", 20), new SolidBrush(Color.Green), new PointF(screenpoint.X, screenpoint.Y)); }
//计算屏幕距离函数 public double ToScreenDistance(GISVertex v1, GISVertex v2) { Point p1 = ToScreenPoint(v1); Point p2 = ToScreenPoint(v2); double ScreenDistance = Math.Sqrt((double)((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y))); Console.WriteLine("ScreenDistance is " + ScreenDistance.ToString()); return(ScreenDistance); }
//根据鼠标点和距离阈值构造点选范围extent public GISExtent BuildExtent(GISVertex vertex, GISView view) { Point p0 = view.ToScreenPoint(vertex); Point p1 = new Point(p0.X + (int)GISConst.MinScreenDistance, p0.Y + (int)GISConst.MinScreenDistance); Point p2 = new Point(p0.X - (int)GISConst.MinScreenDistance, p0.Y - (int)GISConst.MinScreenDistance); GISVertex gmp1 = view.ToMapVertex(p1); GISVertex gmp2 = view.ToMapVertex(p2); return(new GISExtent(gmp1.x, gmp2.x, gmp1.y, gmp2.y)); }
//点到线实体的距离计算 //可以算出最短的距离 但无法获知最近的位置 public double Distance(GISVertex vertex) { double distance = Double.MaxValue; for (int i = 0; i < Vertexes.Count - 1; i++) { distance = Math.Min(GISTools.PointToSegment (Vertexes[i], Vertexes[i + 1], vertex), distance); } return(distance); }
private void BtchangeEsymbol_Click(object sender, EventArgs e) { int symbolsize = Convert.ToInt32(tbsymbolsize.Text); int cls = Convert.ToInt32(tbclass.Text); Color symbolcolor = btsymbolfillcolor.BackColor; List <int> sizes = layer.getSymbolSize(cbattributeEsymbol.SelectedIndex, symbolsize, cls); //新建一个esymbollayer,在点密度中的点将以一个点图层的形式显示出来 GISLayer esymbollayer = new GISLayer("Esymbol", SHAPETYPE.point, layer.Extent); esymbollayer.Selectable = false; //设置为不可选择 esymbollayer.ThematicType = THEMATICTYPE.EqualSymbol; //设置为等比变换型专题地图 //为esymbollayer中每一个对象设置一个thematic for (int i = 0; i < layer.Features.Count; i++) { esymbollayer.Thematics.Add(i, new GISThematic(Color.Black, sizes[i], symbolcolor)); Console.WriteLine(sizes[i]); } //创建symbols点对象,作为esymbollayer的features //默认将符号放于polygon的重心位置 List <GISFeature> symbols = new List <GISFeature>(); for (int i = 0; i < layer.Features.Count; i++) { GISPolygon polygon = (GISPolygon)layer.Features[i].spatialpart; GISVertex vertex = new GISVertex(polygon.centroid); symbols.Add(new GISFeature(new GISPoint(vertex), null)); } esymbollayer.Features = symbols; //先移除之前已有的点密度图层 for (int i = Document.layers.Count - 1; i > 0; i--) { if (Document.layers[i].Name == "Esymbol") { Document.layers.RemoveAt(i); } } Document.layers.Add(esymbollayer);//将esymbollayer添加到document中 在更新地图绘制时会自动绘制layers里面的所有图层 //更新地图绘制 if (sender.Equals(previewes)) { PreviewWindow.UpdateMap(); } else if (sender.Equals(btchangeEsymbol)) { Mapwindow.UpdateMap(); } }
public Point ToScreenPoint(GISVertex onevertex)//地图点到屏幕点转换 { if (Form1.IsMercator) { double ScreenX = (onevertex.mercatorx - MapMinX) / ScaleX; double ScreenY = WinH - (onevertex.mercatory - MapMinY) / ScaleY; Console.WriteLine(ScreenX.ToString() + ScreenY.ToString()); return(new Point((int)ScreenX, (int)ScreenY)); } else { double ScreenX = (onevertex.x - MapMinX) / ScaleX; double ScreenY = WinH - (onevertex.y - MapMinY) / ScaleY; return(new Point((int)ScreenX, (int)ScreenY)); } }
public SelectResult SelectPoint(GISVertex vertex, List <GISFeature> features, GISView view, GISExtent MinSelectExtent) { Double distance = Double.MaxValue; int id = -1; for (int i = 0; i < features.Count; i++) //找最近的feature判断是否有效 { if (MinSelectExtent.IntersectOrNot(features[i].spatialpart.extent) == false) { continue; } GISPoint point = (GISPoint)(features[i].spatialpart); double dist = point.Distance(vertex); if (dist < distance)//每次找到最小的距离并记录id号 { distance = dist; id = i; } } Console.WriteLine("id:" + id.ToString()); //测试id是否存在 Console.WriteLine(features[id].spatialpart.centroid.x.ToString() + "|" + features[id].spatialpart.centroid.y.ToString()); Console.WriteLine("鼠标点到元素点在地图上相距" + distance.ToString()); //此处的distance是features中最近的元素点到鼠标点映射到地图上点的距离 //精选 if (id == -1) //经过遍历 没有与minsextent相交的点则跳出 { SelectedFeature = null; return(SelectResult.TooFar); } else { double screendistance = view.ToScreenDistance(vertex, features[id].spatialpart.centroid); //Console.WriteLine(screendistance); if (screendistance < GISConst.MinScreenDistance) { SelectedFeature = features[id]; return(SelectResult.OK); } else { SelectedFeature = null; return(SelectResult.TooFar);//即使在粗选相交 精选距离也超过了限制 则返回 } } }
public static double PointToSegment(GISVertex A, GISVertex B, GISVertex 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)); }
public SelectResult SelectLine(GISVertex vertex, List <GISFeature> features, GISView view, GISExtent MinSelectExtent) { Double distance = Double.MaxValue; int id = -1; for (int i = 0; i < features.Count; i++) //找最近的feature判断是否有效 { if (MinSelectExtent.IntersectOrNot(features[i].spatialpart.extent) == false) { continue; } GISLine line = (GISLine)(features[i].spatialpart); double dist = line.Distance(vertex); //Console.WriteLine("dist:" + dist); if (dist < distance)//每次找到最小的距离并记录id号 { distance = dist; id = i; } } Console.WriteLine("id:" + id.ToString());//测试id是否存在 //Console.WriteLine(distance); //精选 if (id == -1)//经过遍历 没有与minsextent相交的点则跳出 { SelectedFeature = null; return(SelectResult.TooFar); } else { double screendistance = view.ToScreenDistance(distance); if (screendistance < GISConst.MinScreenDistance) { SelectedFeature = features[id]; return(SelectResult.OK); } else { SelectedFeature = null; return(SelectResult.TooFar);//即使在粗选相交 精选距离也超过了限制 则返回 } } }
public SelectResult Select(GISVertex vertex, List <GISFeature> features, SHAPETYPE shapetype, GISView view) { if (features.Count == 0) { return(SelectResult.EmptySet); } GISExtent MinSelectExtent = BuildExtent(vertex, view);//建立最小选择范围 switch (shapetype) { case SHAPETYPE.point: Console.WriteLine("point"); return(SelectPoint(vertex, features, view, MinSelectExtent)); case SHAPETYPE.line: Console.WriteLine("line"); return(SelectLine(vertex, features, view, MinSelectExtent)); case SHAPETYPE.polygon: Console.WriteLine("polygon"); return(SelectPolygon(vertex, features, view, MinSelectExtent)); } return(SelectResult.UnknownType); }
public double Distance(GISVertex anothervertex) { return(Location.Distance(anothervertex)); }
public double Distance(GISVertex anothervertex) { return(Math.Sqrt((x - anothervertex.x) * (x - anothervertex.x) - (y - anothervertex.y) * (y - anothervertex.y))); }
public GISExtent(double x1, double x2, double y1, double y2) { upright = new GISVertex(Math.Max(x1, x2), Math.Max(y1, y2)); bottomleft = new GISVertex(Math.Min(x1, x2), Math.Min(y1, y2)); }
public GISVertex upright; //外接矩形的左下和右上角的节点 public GISExtent(GISVertex _bottomleft, GISVertex _upright) { bottomleft = _bottomleft; upright = _upright; }
public void CopyFrom(GISVertex v) { x = v.x; y = v.y; }
public void draw(Graphics graphics, GISVertex location, int index) { graphics.DrawString(values[index].ToString(), new Font("宋体", 20), new SolidBrush(Color.Green), new PointF((int)(location.x), (int)(location.y))); }
private void GISPanel_MouseUp(object sender, MouseEventArgs e) { if (document.IsEmpty()) { return; } if (MouseOnMap == false) { return; } MouseOnMap = false; switch (MouseCommand) { case MOUSECOMMAND.Select: //如果CTRL没被按住,就清空选择集 按住CTRL键表示选择多个 即向选择集中新增空间对象 if (Control.ModifierKeys != Keys.Control) { document.ClearSelection(); } //初始化选择结果 SelectResult sr = SelectResult.UnknownType; if (e.X == MouseStartX && e.Y == MouseStartY) { //点选 GISVertex v = view.ToMapVertex(e.Location); sr = document.Select(v, view); } else { //框选 GISExtent extent = view.Rect2Extent(e.X, MouseStartX, e.Y, MouseStartY); sr = document.Select(extent); } if (sr == SelectResult.OK || Control.ModifierKeys != Keys.Control) { UpdateMap(); UpdateAttributeWindow(); } break; case MOUSECOMMAND.Zoomin: if (e.X == MouseStartX && e.Y == MouseStartY) { //单点放大 GISVertex MouseLocation = view.ToMapVertex(e.Location); GISExtent E1 = view.getRealExtent(); double newwidth = E1.getWidth() * GISConst.ZoominFactor; double newheight = E1.getHeight() * GISConst.ZoominFactor; double newminx = MouseLocation.x - (MouseLocation.x - E1.getMinX()) * GISConst.ZoominFactor; double newminy = MouseLocation.y - (MouseLocation.y - E1.getMinY()) * GISConst.ZoominFactor; view.UpdateExtent(new GISExtent(newminx, newminx + newwidth, newminy, newminy + newheight)); } else { //拉框放大 view.UpdateExtent(view.Rect2Extent(e.X, MouseStartX, e.Y, MouseStartY)); } UpdateMap(); break; case MOUSECOMMAND.Zoomout: if (e.X == MouseStartX && e.Y == MouseStartY) { //单点缩小 GISExtent e1 = view.getRealExtent(); GISVertex mouselocation = view.ToMapVertex(e.Location); double newwidth = e1.getWidth() / GISConst.ZoomoutFactor; double newheight = e1.getHeight() / GISConst.ZoomoutFactor; double newminx = mouselocation.x - (mouselocation.x - e1.getMinX()) / GISConst.ZoomoutFactor; double newminy = mouselocation.y - (mouselocation.y - e1.getMinY()) / GISConst.ZoomoutFactor; view.UpdateExtent(new GISExtent(newminx, newminx + newwidth, newminy, newminy + newheight)); } else { //拉框缩小 GISExtent e3 = view.Rect2Extent(e.X, MouseStartX, e.Y, MouseStartY); GISExtent e1 = view.getRealExtent(); double newwidth = e1.getWidth() * e1.getWidth() / e3.getWidth(); double newheight = e1.getHeight() * e1.getHeight() / e3.getHeight(); double newminx = e3.getMinX() - (e3.getMinX() - e1.getMinX()) * newwidth / e1.getWidth(); double newminy = e3.getMinY() - (e3.getMinY() - e1.getMinY()) * newheight / e1.getHeight(); view.UpdateExtent(new GISExtent(newminx, newminx + newwidth, newminy, newminy + newheight)); } UpdateMap(); break; case MOUSECOMMAND.Pan: if (e.X != MouseStartX && e.Y != MouseStartY) { GISExtent e1 = view.getRealExtent(); GISVertex m1 = view.ToMapVertex(new Point(MouseStartX, MouseStartY)); GISVertex m2 = view.ToMapVertex(e.Location); double newwidth = e1.getWidth(); double newheight = e1.getHeight(); double newminx = e1.getMinX() - (m2.x - m1.x); double newminy = e1.getMinY() - (m2.y - m1.y); view.UpdateExtent(new GISExtent(newminx, newminx + newwidth, newminy, newminy + newheight)); UpdateMap(); } break; } }
public GISPoint(GISVertex onevertex, string onestring) { Location = onevertex; Attribute = onestring; }
//public GISVertex Location; **previous code //public string Attribute; public GISPoint(GISVertex onevertex) { centroid = onevertex; extent = new GISExtent(onevertex, onevertex); }
public static double VectorProduct(GISVertex v1, GISVertex v2) { return(v1.x * v2.y - v1.y * v2.x); }
public double Distance(GISVertex anothervertex) { return(centroid.Distance(anothervertex)); }
public SelectResult SelectPolygon(GISVertex vertex, List <GISFeature> features, GISView view, GISExtent MinSelectExtent) { return(SelectResult.TooFar); }