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); }
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="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> /// <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); }
public moMultiPolygon Clone() { moMultiPolygon sMultiPolygon = new moMultiPolygon(); sMultiPolygon._Parts = _Parts.Clone(); sMultiPolygon._MinX = _MinX; sMultiPolygon._MaxX = _MaxX; sMultiPolygon._MinY = _MinY; sMultiPolygon._MaxY = _MaxY; return(sMultiPolygon); }
/// <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 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); }
//绘制复合多边形 internal static void DrawMultiPolygon(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moMultiPolygon multiPolygon, moSymbol symbol) { if (symbol.SymbolType == moSymbolTypeConstant.SimpleFillSymbol) { moSimpleFillSymbol sSymbol = (moSimpleFillSymbol)symbol; if (sSymbol.Visible == true) { DrawMultiPolygonBySimpleFill(g, extent, mapScale, dpm, mpu, multiPolygon, sSymbol); } } }
/// <summary> /// 获取指定复合多边形的一个注记点 /// </summary> /// <param name="multiPolygon"></param> /// <returns></returns> public static moPoint GetLabelPointOfMultiPolygon(moMultiPolygon multiPolygon) { //思路:找到面积最大的环MaxRing,如果只有一个环,则它就是面积最大的环,面积最大的环必定是外环 //在MaxRing的Y坐标极值的中点处做扫描线,求出扫描线与MaxRing的交点序列Intersections,获得X坐标 //最小和最大两个交点P1和P2。 //该扫描线与其他所有环求交点,如果交点位于P1和P2之间,则加入Intersections,否则不加入。 //对Intersections按照X坐标排序,然后两两配对,找出长度最大的一对交点,其中点即为注记点 Int32 sPartCount = multiPolygon.Parts.Count; //(1)求面积最大的环 moPoints sMaxRing; //面积最大的环 Int32 sPartIndex = 0; //面积最大环的索引号 if (sPartCount == 0) { throw new Exception("MultiPolygon has no one part!"); } else if (sPartCount == 1) { sPartIndex = 0; sMaxRing = multiPolygon.Parts.GetItem(0); } else { //求第一个环的面积 double sMaxS = GetPolygonSquare(multiPolygon.Parts.GetItem(0)); //求其他环的面积,保留面积最大者 for (Int32 i = 1; i <= sPartCount - 1; i++) { double sCurS = GetPolygonSquare(multiPolygon.Parts.GetItem(i)); if (sCurS > sMaxS) { sMaxS = sCurS; sPartIndex = i; } } sMaxRing = multiPolygon.Parts.GetItem(sPartIndex); } //(2)求扫描线和面积最大环的交点序列 sMaxRing.UpdateExtent(); double sScanY = (sMaxRing.MinY + sMaxRing.MaxY) / 2; //扫描线Y坐标 List <double> sIntersections = GetIntersectionsBetweenScanAndPolygon(sScanY, sMaxRing); double sMinX = sIntersections.Min(), sMaxX = sIntersections.Max(); //最小最大X坐标 //(3)求扫描线与其他环的交点 for (Int32 i = 0; i <= sPartCount - 1; i++) { if (i == sPartIndex) { continue; //不用再计算最大环的交点 } //与当前环的交点 List <double> sCurIntersections = GetIntersectionsBetweenScanAndPolygon(sScanY, multiPolygon.Parts.GetItem(i)); //加入sIntersections for (Int32 j = 0; j <= sCurIntersections.Count - 1; j++) { if (sCurIntersections[j] > sMinX && sCurIntersections[j] < sMaxX) { sIntersections.Add(sCurIntersections[j]); } } } //(4)对交点序列排序,并两两配对,求出距离最大者 sIntersections.Sort(); Int32 sIntersectionCount = sIntersections.Count; double sMaxDis = double.MinValue; Int32 sIntersectionIndex = 0; for (Int32 i = 0; i <= sIntersectionCount - 2; i += 2) { double sCurDis = sIntersections[i + 1] - sIntersections[i]; if (sCurDis > sMaxDis) { sMaxDis = sCurDis; sIntersectionIndex = i; } } //(5)计算距离最大的一对交点的中点 double sLabelPointX = (sIntersections[sIntersectionIndex] + sIntersections[sIntersectionIndex + 1]) / 2; moPoint sLabelPoint = new moPoint(sLabelPointX, sScanY); return(sLabelPoint); }
/// <summary> /// 指示指定复合多边形是否部分或完全位于指定矩形盒内 /// </summary> /// <param name="multipolygon"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsMultiPolygonPartiallyWithinBox(moMultiPolygon multipolygon, moRectangle box) { //思路:先判断矩形盒是否相交,如是,按如下顺序,满足任何一个条件,则返回True //(1)复合多边形任何一个点位于矩形盒内; //(2)矩形盒任何一个顶点位于复合多边形内 //(3)矩形盒与复合多边形有交点 moRectangle sBox = multipolygon.GetEnvelope(); if (AreBoxesCross(sBox, box) == false) { return(false); } //(1)多边形任何一个点位于矩形盒内 Int32 sPartCount = multipolygon.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multipolygon.Parts.GetItem(i).Count; for (Int32 j = 0; j <= sPointCount - 1; j++) { moPoint sCurPoint = multipolygon.Parts.GetItem(i).GetItem(j); if (IsPointWithinBox(sCurPoint, box) == true) { return(true); } } } //(2)矩形盒任何一个顶点位于多边形内 moPoint sRectPoint = new moPoint(box.MinX, box.MinY); //左下点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MinX, box.MaxY); //左上点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MaxX, box.MaxY); //右上点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MaxX, box.MinY); //右下点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } //(3)矩形盒与复合多边形有交点 for (Int32 i = 0; i <= sPartCount - 1; i++) { moPoints sPoints = multipolygon.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); } } if (IsSegmentCrossBox(sPoints.GetItem(sPointCount - 1), sPoints.GetItem(0), box) == true) { return(true); } } //(4)都不满足,返回false return(false); }
/// <summary> /// 以指定符号绘制指定复合多边形 /// </summary> /// <param name="multiPolygon"></param> /// <param name="symbol"></param> public void DrawMultiPolygon(moMultiPolygon multiPolygon, moSymbol symbol) { moMapDrawingTools.DrawMultiPolygon(_MyGraphics, _Extent, _MapScale, _dpm, _mpu, multiPolygon, symbol); }
/// <summary> /// 绘制所有注记 /// </summary> /// <param name="g"></param> /// <param name="extent"></param> /// <param name="mapScale"></param> /// <param name="dpm"></param> /// <param name="mpu"></param> /// <param name="placedLabelExtents"></param> internal void DrawLabels(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, List <RectangleF> placedLabelExtents) { if (_LabelRenderer == null) { return; } if (_LabelRenderer.LabelFeatures == false) { return; } Int32 sFieldIndex = _AttributeFields.FindField(_LabelRenderer.Field); if (sFieldIndex < 0) { return; } Int32 sFeatureCount = _Features.Count; for (Int32 i = 0; i <= sFeatureCount - 1; i++) { moFeature sFeature = _Features.GetItem(i); if (IsFeatureInExtent(sFeature, extent) == false) { //要素不位于显示范围内,不显示注记 continue; } if (sFeature.Symbol == null) { //要素没有配置符号,不显示注记 continue; } if (IsFeatureSymbolVisible(sFeature) == false) { //要素符号不可见,自然就不显示注记 continue; } string sLabelText = GetValueString(sFeature.Attributes.GetItem(sFieldIndex)); if (sLabelText == string.Empty) { //注记文本为空,不显示注记 continue; } //根据要素几何类型采用相应的配置方案 if (sFeature.ShapeType == moGeometryTypeConstant.Point) { //点要素,取点的右上为定位点,但要考虑点符号的大小 //(1)复制符号 moTextSymbol sTextSymbol; //最终绘制注记所采用的符号 sTextSymbol = _LabelRenderer.TextSymbol.Clone(); //复制符号 //(2)计算定位点并设置符号 PointF sSrcLabelPoint; //定位点的屏幕坐标 moPoint sPoint = (moPoint)sFeature.Geometry; PointF sSrcPoint = FromMapPoint(extent, mapScale, dpm, mpu, sPoint); //点要素的屏幕坐标 moSimpleMarkerSymbol sMarkerSymbol = (moSimpleMarkerSymbol)sFeature.Symbol; float sSymbolSize = (float)(sMarkerSymbol.Size / 1000 * dpm); //符号的屏幕尺寸 //右上方并设置符号 sSrcLabelPoint = new PointF(sSrcPoint.X + sSymbolSize / 2, sSrcPoint.Y - sSymbolSize / 2); sTextSymbol.Alignment = moTextSymbolAlignmentConstant.BottomLeft; //(3)计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, sTextSymbol); //(4)冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } else if (sFeature.ShapeType == moGeometryTypeConstant.MultiPolyline) { //线要素,为每个部分的中点配置一个注记 //(1)获取符号,线要素无需复制符号 moTextSymbol sTextSymbol = _LabelRenderer.TextSymbol; //(2)对每个部分进行配置 moMultiPolyline sMultiPolyline = (moMultiPolyline)sFeature.Geometry; Int32 sPartCount = sMultiPolyline.Parts.Count; for (Int32 j = 0; j <= sPartCount - 1; j++) { //获取注记 moPoint sMapLabelPoint = moMapTools.GetMidPointOfPolyline(sMultiPolyline.Parts.GetItem(j)); PointF sSrcLabelPoint = FromMapPoint(extent, mapScale, dpm, mpu, sMapLabelPoint); //计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, _LabelRenderer.TextSymbol); //冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } } else if (sFeature.ShapeType == moGeometryTypeConstant.MultiPolygon) { //面要素,为面积最大的外环及其内环所构成的多边形配置一个注记 //(1)获取符号,面要素无需复制符号 moTextSymbol sTextSymbol = _LabelRenderer.TextSymbol; //(2)获取注记点 moMultiPolygon sMultiPolygon = (moMultiPolygon)sFeature.Geometry; moPoint sMapLabelPoint = moMapTools.GetLabelPointOfMultiPolygon(sMultiPolygon); PointF sSrcLabelPoint = FromMapPoint(extent, mapScale, dpm, mpu, sMapLabelPoint); //(3)计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, _LabelRenderer.TextSymbol); //(4)冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } else { throw new Exception("Invalid shape type!"); } } }