/// <summary> /// /// </summary> /// <param name="selectingBox"></param> /// <returns></returns> private moFeatures SearchFeaturesByBox(moRectangle selectingBox) { moFeatures sSelectedFeatures = new moFeatures(); Int32 sFeatureCount = _Features.Count; for (Int32 i = 0; i <= sFeatureCount - 1; i++) { if (_ShapeType == moGeometryTypeConstant.Point) { moPoint sPoint = (moPoint)_Features.GetItem(i).Geometry; if (moMapTools.IsPointWithinBox(sPoint, selectingBox) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } else if (_ShapeType == moGeometryTypeConstant.MultiPolyline) { moMultiPolyline sMultiPolyline = (moMultiPolyline)_Features.GetItem(i).Geometry; if (moMapTools.IsMultiPolylinePartiallyWithinBox(sMultiPolyline, selectingBox) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } else if (_ShapeType == moGeometryTypeConstant.MultiPolygon) { moMultiPolygon sMultiPolygon = (moMultiPolygon)_Features.GetItem(i).Geometry; if (moMapTools.IsMultiPolygonPartiallyWithinBox(sMultiPolygon, selectingBox) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } } return(sSelectedFeatures); }
/// <summary> /// 获取地图窗口对应的地图范围(地图坐标) /// </summary> /// <returns></returns> public moRectangle GetExtent() { //定义变量 double sMinX = double.MaxValue, sMaxX = double.MinValue; double sMinY = double.MaxValue, sMaxY = double.MinValue; moRectangle sExtent; //如果工作区为空,则返回空矩形 Rectangle sClientRect = this.ClientRectangle; if (sClientRect.IsEmpty == true) { sExtent = new moRectangle(sMinX, sMaxX, sMinY, sMaxY); return(sExtent); } //定义工作区左上点和右下点的屏幕坐标 moPoint sTopLeftScreenPoint = new moPoint(0, 0); moPoint sBottomRightScreenPoint = new moPoint(sClientRect.Width, sClientRect.Height); //获取工作区左上点和右下点的地图坐标 moPoint sTopLeftMapPoint = mMapDrawingReference.ToMapPoint(sTopLeftScreenPoint.X, sTopLeftScreenPoint.Y); moPoint sBottomRightMapPoint = mMapDrawingReference.ToMapPoint(sBottomRightScreenPoint.X, sBottomRightScreenPoint.Y); //定义范围矩形 sMinX = sTopLeftMapPoint.X; sMaxX = sBottomRightMapPoint.X; sMinY = sBottomRightMapPoint.Y; sMaxY = sTopLeftMapPoint.Y; sExtent = new moRectangle(sMinX, sMaxX, sMinY, sMaxY); return(sExtent); }
public moFeature Clone() { moGeometryTypeConstant sShapeType = _ShapeType; moGeometry sGeometry = null; moAttributes sAttributes = _Attributes.Clone(); if (_ShapeType == moGeometryTypeConstant.Point) { moPoint sPoint = (moPoint)_Geometry; sGeometry = sPoint.Clone(); } else if (_ShapeType == moGeometryTypeConstant.MultiPolyline) { moMultiPolyline sMultiPolyline = (moMultiPolyline)_Geometry; sGeometry = sMultiPolyline.Clone(); } else if (_ShapeType == moGeometryTypeConstant.MultiPolygon) { moMultiPolygon sMultiPolygon = (moMultiPolygon)_Geometry; sGeometry = sMultiPolygon.Clone(); } moFeature sFeature = new moFeature(sShapeType, sGeometry, sAttributes); return(sFeature); }
/// <summary> /// 获取指定折线的中点 /// </summary> /// <param name="points"></param> /// <returns></returns> public static moPoint GetMidPointOfPolyline(moPoints points) { Int32 sPointCount = points.Count; List <double> sDises = new List <double>(); //所有顶点至起点的距离 sDises.Add(0); //第一个点至起点的距离 for (Int32 i = 1; i <= sPointCount - 1; i++) { double sCurDis = sDises.Last() + GetDistance(points.GetItem(i).X, points.GetItem(i).Y, points.GetItem(i - 1).X, points.GetItem(i - 1).Y); sDises.Add(sCurDis); } //查找中点所在的线段索引号 Int32 sIndex = 0; double sMidDis = sDises.Last() / 2; //中点与起点的距离 for (Int32 i = 0; i <= sPointCount - 2; i++) { if (sMidDis >= sDises[i] && sMidDis < sDises[i + 1]) { sIndex = i; break; } } //计算中点 double x1 = points.GetItem(sIndex).X, y1 = points.GetItem(sIndex).Y; double x2 = points.GetItem(sIndex + 1).X, y2 = points.GetItem(sIndex + 1).Y; double sSegDis = GetDistance(x1, y1, x2, y2); double x = x1 + (x2 - x1) * (sMidDis - sDises[sIndex]) / sSegDis; double y = y1 + (y2 - y1) * (sMidDis - sDises[sIndex]) / sSegDis; moPoint sMidPoint = new moPoint(x, y); return(sMidPoint); }
/// <summary> /// 根据指定点搜索要素 /// </summary> /// <param name="point"></param> /// <param name="tolerance"></param> /// <returns></returns> public moFeatures SearchFeaturesByPoint(moPoint point, double tolerance) { moFeatures sSelectedFeatures = new moFeatures(); Int32 sFeatureCount = _Features.Count; for (Int32 i = 0; i <= sFeatureCount - 1; i++) { if (_ShapeType == moGeometryTypeConstant.Point) { moPoint sPoint = (moPoint)_Features.GetItem(i).Geometry; if (moMapTools.IsPointOnPoint(point, sPoint, tolerance) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } else if (_ShapeType == moGeometryTypeConstant.MultiPolyline) { moMultiPolyline sMultiPolyline = (moMultiPolyline)_Features.GetItem(i).Geometry; if (moMapTools.IsPointOnMultiPolyline(point, sMultiPolyline, tolerance) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } else if (_ShapeType == moGeometryTypeConstant.MultiPolygon) { moMultiPolygon sMultiPolygon = (moMultiPolygon)_Features.GetItem(i).Geometry; if (moMapTools.IsPointWithinMultiPolygon(point, sMultiPolygon) == true) { sSelectedFeatures.Add(_Features.GetItem(i)); } } } return(sSelectedFeatures); }
internal static void DrawGeometry(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moGeometry geometry, moSymbol symbol) { if (extent == null) { return; } if (geometry == null) { return; } if (symbol == null) { return; } if (geometry.GetType() == typeof(moPoint)) { moPoint sPoint = (moPoint)geometry; DrawPoint(g, extent, mapScale, dpm, mpu, sPoint, symbol); } else if (geometry.GetType() == typeof(moMultiPolyline)) { moMultiPolyline sMultiPolyline = (moMultiPolyline)geometry; DrawMultiPolyline(g, extent, mapScale, dpm, mpu, sMultiPolyline, symbol); } else if (geometry.GetType() == typeof(moMultiPolygon)) { moMultiPolygon sMultiPolygon = (moMultiPolygon)geometry; DrawMultiPolygon(g, extent, mapScale, dpm, mpu, sMultiPolygon, symbol); } }
/// <summary> /// 指示两条线段是否有交点 /// </summary> /// <param name="sPoint1"></param> /// <param name="ePoint1"></param> /// <param name="sPoint2"></param> /// <param name="ePoint2"></param> /// <returns></returns> internal static bool AreSegmentsCross(moPoint sPoint1, moPoint ePoint1, moPoint sPoint2, moPoint ePoint2) { //思路:采用参数方程求解,原理如下 //线段1参数方程x = sx1 + (ex1 - sx1) * t, y = sy1 + (ey1 - sy1) * t //线段2参数方程x = sx2 + (ex2 - sx2) * l, y = sy2 + (ey2 - sy2) * l //解参数方程组: (1)sx1 + (ex1 - sx1) * t = sx2 + (ex2 - sx2) * l; (2)sy1 + (ey1 - sy1) * t = sy2 + (ey2 - sy2) * l //如果0 <= t <= 1 and 0 <= l <= 1,则有交点 double sx1 = sPoint1.X, sy1 = sPoint1.Y; //第一条线段起点 double ex1 = ePoint1.X, ey1 = ePoint1.Y; //第一条线段终点 double sx2 = sPoint2.X, sy2 = sPoint2.Y; //第二条线段起点 double ex2 = ePoint2.X, ey2 = ePoint2.Y; //第二条线段终点 double deltaX1 = ex1 - sx1, deltaY1 = ey1 - sy1; double deltaX2 = ex2 - sx2, deltaY2 = ey2 - sy2; //如果两条线段平行则返回False if (deltaY2 * deltaX1 - deltaX2 * deltaY1 == 0) { return(false); } //如果不平行,则求交点 double t, l; t = (deltaX2 * (sy1 - sy2) - deltaY2 * (sx1 - sx2)) / (deltaX1 * deltaY2 - deltaX2 * deltaY1); l = (deltaX1 * (sy1 - sy2) - deltaY1 * (sx1 - sx2)) / (deltaX1 * deltaY2 - deltaX2 * deltaY1); if (t >= 0 && t <= 1 && l >= 0 && l <= 1) { return(true); } else { return(false); } }
//采用简单线符号绘制复合折线 private static void DrawMultiPolylineBySimpleLine(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moMultiPolyline multiPolyline, moSimpleLineSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 Int32 sPartCount = multiPolyline.Parts.Count; //简单折线的数目 GraphicsPath sGraphicPath = new GraphicsPath(); //定义复合多边形,用于屏幕绘制 for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multiPolyline.Parts.GetItem(i).Count; //当前简单折线的顶点数目 PointF[] sScreenPoints = new PointF[sPointCount]; for (Int32 j = 0; j <= sPointCount - 1; j++) { PointF sScreenPoint = new PointF(); moPoint sCurPoint = multiPolyline.Parts.GetItem(i).GetItem(j); sScreenPoint.X = (float)((sCurPoint.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint.Y = (float)((sOffsetY - sCurPoint.Y) * mpu / mapScale * dpm); sScreenPoints[j] = sScreenPoint; } sGraphicPath.AddLines(sScreenPoints); sGraphicPath.StartFigure(); } //(2)绘制 Pen sPen = new Pen(symbol.Color, (float)(symbol.Size / 1000 * dpm)); sPen.DashStyle = (DashStyle)symbol.Style; g.DrawPath(sPen, sGraphicPath); sPen.Dispose(); }
/// <summary> /// 指定的扫描线与指定线段是否相交 /// </summary> /// <param name="scanY"></param> /// <param name="sPoint"></param> /// <param name="ePoint"></param> /// <returns></returns> internal static bool IsScanCrossSegment(double scanY, moPoint sPoint, moPoint ePoint) { if (sPoint.Y == ePoint.Y) { //与扫描线平行 return(false); } if (sPoint.Y > scanY && ePoint.Y > scanY) { //线段在扫描线上边 return(false); } if (sPoint.Y < scanY && ePoint.Y < scanY) { //线段在扫描线下边 return(false); } if (sPoint.Y == scanY && ePoint.Y > scanY) { //交点为下端点 return(false); } if (ePoint.Y == scanY && sPoint.Y > scanY) { //交点为下端点 return(false); } return(true); }
//将屏幕坐标转换为地图坐标 internal moPoint ToMapPoint(double x, double y) { double sX = x / _dpm / _mpu * _MapScale + _OffsetX; double sY = _OffsetY - y / _dpm / _mpu * _MapScale; moPoint sPoint = new moPoint(sX, sY); return(sPoint); }
//将地图坐标转换为屏幕坐标 internal moPoint FromMapPoint(double x, double y) { double sX = (x - _OffsetX) / _MapScale * _dpm * _mpu; double sY = (_OffsetY - y) / _MapScale * _dpm * _mpu; moPoint sPoint = new moPoint(sX, sY); return(sPoint); }
/// <summary> /// 指示在指定容限下,一个点是否位于另一个点上 /// </summary> /// <param name="point"></param> /// <param name="pointOverlapped"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool IsPointOnPoint(moPoint point, moPoint pointOverlapped, double tolerance) { if (GetDistance(point.X, point.Y, pointOverlapped.X, pointOverlapped.Y) <= tolerance) { return(true); } else { return(false); } }
/// <summary> /// 指示指定点是否位于指定矩形盒内 /// </summary> /// <param name="point"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsPointWithinBox(moPoint point, moRectangle box) { if (point.X >= box.MinX && point.X <= box.MaxX && point.Y >= box.MinY && point.Y <= box.MaxY) { return(true); } else { return(false); } }
/// <summary> /// 指示指定线段是否与指定矩形盒相交 /// </summary> /// <param name="sPoint"></param> /// <param name="ePoint"></param> /// <param name="box"></param> /// <returns></returns> internal static bool IsSegmentCrossBox(moPoint sPoint, moPoint ePoint, moRectangle box) { //先判断线段两个端点是否全部位于矩形盒某条边的外侧,如是,则返回False if (sPoint.X < box.MinX && ePoint.X < box.MinX) { //两个端点位于矩形左边的外侧 return(false); } if (sPoint.X > box.MaxX && ePoint.X > box.MaxX) { //两个端点位于矩形右边的外侧 return(false); } if (sPoint.Y < box.MinY && ePoint.Y < box.MinY) { //两个端点位于矩形底边的外侧 return(false); } if (sPoint.Y > box.MaxY && ePoint.Y > box.MaxY) { //两个端点位于矩形上边的外侧 return(false); } //定义四个顶点 moPoint sPoint1 = new moPoint(box.MinX, box.MaxY); //矩形左上点 moPoint sPoint2 = new moPoint(box.MaxX, box.MaxY); //矩形右上点 moPoint sPoint3 = new moPoint(box.MaxX, box.MinY); //矩形右下点 moPoint sPoint4 = new moPoint(box.MinX, box.MinY); //矩形左下点 //将每条边与线段求交 if (AreSegmentsCross(sPoint, ePoint, sPoint1, sPoint2) == true) { //与上边有交点 return(true); } if (AreSegmentsCross(sPoint, ePoint, sPoint3, sPoint4) == true) { //与下边有交点 return(true); } if (AreSegmentsCross(sPoint, ePoint, sPoint1, sPoint4) == true) { //与左边有交点 return(true); } if (AreSegmentsCross(sPoint, ePoint, sPoint2, sPoint3) == true) { //与右边有交点 return(true); } return(false); }
/// <summary> /// 以指定中心和系数对地图进行缩放 /// </summary> /// <param name="center"></param> /// <param name="ratio"></param> public void ZoomByCenter(moPoint center, double ratio) { mMapDrawingReference.ZoomByCenter(center, ratio); this.UseWaitCursor = true; DrawBufferMap1(); DrawBufferMap2(); this.UseWaitCursor = false; Refresh(); //触发事件 if (MapScaleChanged != null) { MapScaleChanged(this); } }
//绘制点集合(多点) internal static void DrawPoints(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoints points, moSymbol symbol) { if (symbol.SymbolType == moSymbolTypeConstant.SimpleMarkerSymbol) { moSimpleMarkerSymbol sSymbol = (moSimpleMarkerSymbol)symbol; if (sSymbol.Visible == true) { Int32 sPointCount = points.Count; for (Int32 i = 0; i <= sPointCount - 1; i++) { moPoint sPoint = points.GetItem(i); DrawPointBySimpleMarker(g, extent, mapScale, dpm, mpu, sPoint, sSymbol); } } } }
/// <summary> /// 克隆 /// </summary> /// <returns></returns> public moPoints Clone() { moPoints sPoints = new moPoints(); Int32 sPointCount = _Points.Count; for (Int32 i = 0; i <= sPointCount - 1; i++) { moPoint sPoint = new moPoint(_Points[i].X, _Points[i].Y); sPoints.Add(sPoint); } sPoints._MinX = _MinX; sPoints._MaxX = _MaxX; sPoints._MinY = _MinY; sPoints._MaxY = _MaxY; return(sPoints); }
/// <summary> /// 根据矩形盒执行搜索,返回选中的要素集合 /// </summary> /// <param name="selectionBox"></param> /// <param name="tolerance"></param> /// <returns></returns> public moFeatures SearchByBox(moRectangle selectingBox, double tolerance) { //说明:仅考虑一种选择模式 moFeatures sSelection = null; if (selectingBox.Width == 0 && selectingBox.Height == 0) { //点选 moPoint sSelectingPoint = new moPoint(selectingBox.MinX, selectingBox.MinY); sSelection = SearchFeaturesByPoint(sSelectingPoint, tolerance); } else { //框选 sSelection = SearchFeaturesByBox(selectingBox); } return(sSelection); }
/// <summary> /// 一条水平向右的射线与一条线段是否相交 /// </summary> /// <param name="point"></param> /// <param name="sPoint"></param> /// <param name="ePoint"></param> /// <returns></returns> internal static bool IsRayCrossSegment(moPoint point, moPoint sPoint, moPoint ePoint) { if (sPoint.Y == ePoint.Y) { //与射线平行 return(false); } if (sPoint.Y > point.Y && ePoint.Y > point.Y) { //线段在射线上边 return(false); } if (sPoint.Y < point.Y && ePoint.Y < point.Y) { //线段在射线下边 return(false); } if (sPoint.Y == point.Y && ePoint.Y > point.Y) { //交点为下端点 return(false); } if (ePoint.Y == point.Y && sPoint.Y > point.Y) { //交点为下端点 return(false); } if (sPoint.X < point.X && ePoint.X < point.X) { //线段位于起点的左边 return(false); } double x = ePoint.X - (ePoint.X - sPoint.X) * (ePoint.Y - point.Y) / (ePoint.Y - sPoint.Y); if (x < point.X) { //交点在射线起点的左侧,故视为无交点 return(false); } return(true); }
//采用简单线符号绘制线段 private static void DrawLineBySimpleLine(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoint point1, moPoint point2, moSimpleLineSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 PointF sScreenPoint1 = new PointF(); PointF sScreenPoint2 = new PointF(); sScreenPoint1.X = (float)((point1.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint1.Y = (float)((sOffsetY - point1.Y) * mpu / mapScale * dpm); sScreenPoint2.X = (float)((point2.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint2.Y = (float)((sOffsetY - point2.Y) * mpu / mapScale * dpm); //(2)绘制 Pen sPen = new Pen(symbol.Color, (float)(symbol.Size / 1000 * dpm)); sPen.DashStyle = (DashStyle)symbol.Style; g.DrawLine(sPen, sScreenPoint1, sScreenPoint2); sPen.Dispose(); }
/// <summary> /// 指示指定复合折线是否部分或完全位于指定矩形盒内 /// </summary> /// <param name="multipolyline"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsMultiPolylinePartiallyWithinBox(moMultiPolyline multipolyline, moRectangle box) { //思路:先判断矩形盒是否相交,如是,按如下顺序,满足任何一个条件,则返回True //(1)复合折线任何一个点位于矩形盒内; //(2)矩形盒与复合折线有交点 moRectangle sBox = multipolyline.GetEnvelope(); if (AreBoxesCross(sBox, box) == false) { return(false); } //(1)复合折线任何一个点位于矩形盒内; Int32 sPartCount = multipolyline.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multipolyline.Parts.GetItem(i).Count; for (Int32 j = 0; j <= sPointCount - 1; j++) { moPoint sCurPoint = multipolyline.Parts.GetItem(i).GetItem(j); if (IsPointWithinBox(sCurPoint, box) == true) { return(true); } } } //(2)矩形盒与复合折线有交点 for (Int32 i = 0; i <= sPartCount - 1; i++) { moPoints sPoints = multipolyline.Parts.GetItem(i); Int32 sPointCount = sPoints.Count; for (Int32 j = 0; j <= sPointCount - 2; j++) { if (IsSegmentCrossBox(sPoints.GetItem(j), sPoints.GetItem(j + 1), box) == true) { return(true); } } } //(3)都不满足,返回false return(false); }
/// <summary> /// 求一条水平向右的射线与一个多边形的交点个数 /// </summary> /// <param name="point"></param> /// <param name="polygon"></param> /// <returns></returns> internal static Int32 GetIntersectionCountBetweenRayAndPolygon(moPoint point, moPoints points) { Int32 sIntersectionCount = 0; Int32 sPointCount = points.Count; if (IsRayCrossSegment(point, points.GetItem(sPointCount - 1), points.GetItem(0)) == true) { //起点与最后一点的连线与射线有交点 sIntersectionCount = sIntersectionCount + 1; } //求射线与其他边的交点 for (Int32 i = 0; i <= sPointCount - 2; i++) { if (IsRayCrossSegment(point, points.GetItem(i), points.GetItem(i + 1)) == true) { sIntersectionCount = sIntersectionCount + 1; } } return(sIntersectionCount); }
/// <summary> /// 指示在指定容限下,指定点是否位于指定的折线上 /// </summary> /// <param name="point"></param> /// <param name="points"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool IsPointOnPolyline(moPoint point, moPoints points, double tolerance) { moRectangle sBox = new moRectangle(points.MinX - tolerance, points.MaxX + tolerance, points.MinY - tolerance, points.MaxY + tolerance); if (IsPointWithinBox(point, sBox) == false) { return(false); } Int32 sPointCount = points.Count; for (Int32 i = 0; i <= sPointCount - 2; i++) { if (GetDistanceFromPointToSegment(point.X, point.Y, points.GetItem(i).X, points.GetItem(i).Y, points.GetItem(i + 1).X, points.GetItem(i + 1).Y) <= tolerance) { return(true); } } return(false); }
/// <summary> /// 指示在指定容限下,指定点是否位于指定复合折线上 /// </summary> /// <param name="point"></param> /// <param name="multiPolyline"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool IsPointOnMultiPolyline(moPoint point, moMultiPolyline multiPolyline, double tolerance) { moRectangle sBox = new moRectangle(multiPolyline.MinX - tolerance, multiPolyline.MaxX + tolerance, multiPolyline.MinY - tolerance, multiPolyline.MaxY + tolerance); if (IsPointWithinBox(point, sBox) == false) { return(false); } Int32 sPartCount = multiPolyline.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { if (IsPointOnPolyline(point, multiPolyline.Parts.GetItem(i), tolerance) == true) { return(true); } } return(false); }
//以指定中心和指定系数进行缩放 internal void ZoomByCenter(moPoint center, double ratio) { double sMapScale = _MapScale / ratio; //新的比例尺 if (sMapScale > mcMaxMapScale) { sMapScale = mcMaxMapScale; } else if (sMapScale < mcMinMapScale) { sMapScale = mcMinMapScale; } double sRatio = _MapScale / sMapScale; //实际的缩放系数 double sOffsetX = _OffsetX + (1 - 1 / sRatio) * (center.X - _OffsetX); double sOffsetY = _OffsetY + (1 - 1 / sRatio) * (center.Y - _OffsetY); _OffsetX = sOffsetX; _OffsetY = sOffsetY; _MapScale = sMapScale; }
/// <summary> /// 获取外包矩形 /// </summary> /// <returns></returns> public moRectangle GetEnvelope() { moRectangle sRect = null; if (_ShapeType == moGeometryTypeConstant.Point) { moPoint sPoint = (moPoint)_Geometry; sRect = new moRectangle(sPoint.X, sPoint.X, sPoint.Y, sPoint.Y); } else if (_ShapeType == moGeometryTypeConstant.MultiPolyline) { moMultiPolyline sMultiPolyline = (moMultiPolyline)_Geometry; sRect = sMultiPolyline.GetEnvelope(); } else { moMultiPolygon sMultiPolygon = (moMultiPolygon)_Geometry; sRect = sMultiPolygon.GetEnvelope(); } return(sRect); }
//采用简单点符号绘制点 private static void DrawPointBySimpleMarker(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoint point, moSimpleMarkerSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 PointF sScreenPoint = new PointF(); sScreenPoint.X = (float)((point.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint.Y = (float)((sOffsetY - point.Y) * mpu / mapScale * dpm); //(2)计算符号大小 float sSize = (float)(symbol.Size / 1000 * dpm); //符号大小,像素 if (sSize < 1) { sSize = 1; } //(3)定义绘制区域并绘制 Rectangle sDrawingArea = new Rectangle((Int32)(sScreenPoint.X - sSize / 2), (Int32)(sScreenPoint.Y - sSize / 2), (Int32)sSize, (Int32)sSize); DrawSimpleMarker(g, sDrawingArea, dpm, symbol); }
//采用简单填充符号绘制复合多边形 private static void DrawMultiPolygonBySimpleFill(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moMultiPolygon multiPolygon, moSimpleFillSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 Int32 sPartCount = multiPolygon.Parts.Count; //简单多边形的数目 GraphicsPath sGraphicPath = new GraphicsPath(); //定义复合多边形,用于屏幕绘制 for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multiPolygon.Parts.GetItem(i).Count; //当前简单多边形的顶点数目 PointF[] sScreenPoints = new PointF[sPointCount]; for (Int32 j = 0; j <= sPointCount - 1; j++) { PointF sScreenPoint = new PointF(); moPoint sCurPoint = multiPolygon.Parts.GetItem(i).GetItem(j); sScreenPoint.X = (float)((sCurPoint.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint.Y = (float)((sOffsetY - sCurPoint.Y) * mpu / mapScale * dpm); sScreenPoints[j] = sScreenPoint; } sGraphicPath.AddPolygon(sScreenPoints); } //(2)填充 SolidBrush sBrush = new SolidBrush(symbol.Color); g.FillPath(sBrush, sGraphicPath); sBrush.Dispose(); //(3)绘制边界 if (symbol.Outline.SymbolType == moSymbolTypeConstant.SimpleLineSymbol) { moSimpleLineSymbol sOutline = symbol.Outline; if (sOutline.Visible == true) { Pen sPen = new Pen(sOutline.Color, (float)(sOutline.Size / 1000 * dpm)); sPen.DashStyle = (DashStyle)sOutline.Style; g.DrawPath(sPen, sGraphicPath); sPen.Dispose(); } } }
private void MFlashControler_NeedDrawFlashShapes(object sender, moShape[] shapes) { double sMapScale = mMapDrawingReference.MapScale; double dpm = mMapDrawingReference.dpm; double mpu = mMapDrawingReference.mpu; moRectangle sExtent = GetExtent(); Graphics g = Graphics.FromImage(mBufferMap2); Int32 sShapeCount = shapes.Length; for (Int32 i = 0; i <= sShapeCount - 1; i++) { if (shapes[i].GetType() == typeof(moPoint)) { moPoint sPoint = (moPoint)shapes[i]; moMapDrawingTools.DrawPoint(g, sExtent, sMapScale, dpm, mpu, sPoint, mFlashPointSymbol); } else if (shapes[i].GetType() == typeof(moPoints)) { moPoints sPoints = (moPoints)shapes[i]; moMapDrawingTools.DrawPoints(g, sExtent, sMapScale, dpm, mpu, sPoints, mFlashPointSymbol); } else if (shapes[i].GetType() == typeof(moRectangle)) { moRectangle sRect = (moRectangle)shapes[i]; moMapDrawingTools.DrawRectangle(g, sExtent, sMapScale, dpm, mpu, sRect, mFlashFillSymbol); } else if (shapes[i].GetType() == typeof(moMultiPolyline)) { moMultiPolyline sMultiPolyline = (moMultiPolyline)shapes[i]; moMapDrawingTools.DrawMultiPolyline(g, sExtent, sMapScale, dpm, mpu, sMultiPolyline, mFlashLineSymbol); } else if (shapes[i].GetType() == typeof(moMultiPolygon)) { moMultiPolygon sMultiPolygon = (moMultiPolygon)shapes[i]; moMapDrawingTools.DrawMultiPolygon(g, sExtent, sMapScale, dpm, mpu, sMultiPolygon, mFlashFillSymbol); } } g.Dispose(); Refresh(); }
/// <summary> /// 指示指定点是否位于指定复合多边形内 /// </summary> /// <param name="point"></param> /// <param name="multiPolygon"></param> /// <returns></returns> public static bool IsPointWithinMultiPolygon(moPoint point, moMultiPolygon multiPolygon) { //(1)判断点是否位于外包矩形内,如否则返回否 moRectangle sExtent = multiPolygon.GetEnvelope(); if (IsPointWithinBox(point, sExtent) == false) { return(false); } //(2)射线法求交点个数 Int32 sIntersectionCount = 0; //交点个数 Int32 sPartCount = multiPolygon.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { sIntersectionCount = sIntersectionCount + GetIntersectionCountBetweenRayAndPolygon(point, multiPolygon.Parts.GetItem(i)); } if (sIntersectionCount % 2 == 1) { //奇数个,位于多边形内 return(true); } return(false); }