public PolylineFeature(PolylineFeature feature) { m_oStyle = feature.m_oStyle; m_oParts = new List<Part>(); foreach (Part part in feature.m_oParts) { Part newPart = new Part(); m_oParts.Add(newPart); foreach (DPoint point in part.Points) { newPart.Points.Add(new DPoint(point)); } } }
/// <summary> /// Casts a point onto polyline and returns location of its projection. /// </summary> /// <param name="feature">feature of polyline type</param> /// <param name="part">part number to analyse</param> /// <param name="x">point being cast x coord</param> /// <param name="y">point being cast y coord</param> /// <param name="a">normalized cast location along the polyline part [0..1]</param> /// <param name="x_cast">cast x location on the polyline</param> /// <param name="y_cast">cast y location on the polyline</param> /// <param name="dDist">distance of point and polyline</param> /// <param name="dPolyLen">calculated polyline length</param> /// <param name="segNo">number of polyline segment that was closest (0-based)</param> /// <param name="a_seg">normalized position within polyline segment (note that a_seg might be outside of 0..1 range). Value smaller than 0 or greater than 1 denotes, that point is cast to end point of segment.</param> /// <param name="b_seg">distance from a line defined by polyline segment. Side is indicated by sign: positive for right side, negative for left side.</param> public void castToPolyline(PolylineFeature feature, int part, double x, double y, out double a, out double x_cast, out double y_cast, out double dDist, out double dPolyLen, out int segNo, out double a_seg, out double b_seg) { if (feature == null) throw new Exception("Invalid parameter: feature can not be null."); if (part < 0 || part > feature.m_oParts.Count) throw new Exception("Invalid parameter: part."); Part polylinePart = feature.m_oParts[part]; if (polylinePart.Points.Count == 0) { dDist = double.MaxValue; a = 0; x_cast = double.MaxValue; y_cast = double.MaxValue; dPolyLen = 0; segNo = -1; a_seg = 1; b_seg = 1; return; } double a_tmp, b_tmp; double dSegLen; double dDistMin = -1; double dDistTmp = -1; dDist = 0; dPolyLen = 0; a = 0; a_seg = 0; b_seg = 0; segNo = 0; x_cast = 0; y_cast = 0; for (int j = 1; j < polylinePart.Points.Count; j++) { double ax, ay, bx, by; ax = polylinePart.Points[j - 1].X; ay = polylinePart.Points[j - 1].Y; bx = polylinePart.Points[j].X; by = polylinePart.Points[j].Y; dSegLen = Math.Sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by)); if (dSegLen > 0) { // a=0..1 -> rzut punktu x jest miedzy poczatkiem i koncem odcinka ab a_tmp = ((x - ax) * (bx - ax) + (y - ay) * (by - ay)) / ((bx - ax) * (bx - ax) + (by - ay) * (by - ay)); b_tmp = ((bx - ax) * (ay - y) - (by - ay) * (ax - x)) / dSegLen; if (a_tmp > 0 && a_tmp < 1) { // policz odleglosc w rzucie do odcinka dDistTmp = Math.Abs(b_tmp); } else if (a_tmp >= 1) { dDistTmp = Math.Sqrt((bx - x) * (bx - x) + (by - y) * (by - y)); } else { dDistTmp = Math.Sqrt((ax - x) * (ax - x) + (ay - y) * (ay - y)); } } else { // ignore this segment a_tmp = 0; b_tmp = 0; dDistTmp = Math.Sqrt((ax - x) * (ax - x) + (ay - y) * (ay - y)); } if (dDistTmp < dDistMin || dDistMin == -1) { a_seg = a_tmp; b_seg = b_tmp; segNo = j - 1; dDist = dDistTmp; dDistMin = dDistTmp; double dA_tmp; dA_tmp = a_seg; if (dA_tmp > 1) dA_tmp = 1; if (dA_tmp < 0) dA_tmp = 0; a = dPolyLen + dA_tmp * dSegLen; } dPolyLen += dSegLen; } if (dPolyLen == 0) throw new Exception("Polyline length can not be zero."); a = a / dPolyLen; { double ax, ay, bx, by; ax = polylinePart.Points[segNo].X; ay = polylinePart.Points[segNo].Y; bx = polylinePart.Points[segNo + 1].X; by = polylinePart.Points[segNo + 1].Y; if (a_seg >= 0 && a_seg <= 1) { x_cast = ax + (bx - ax) * a_seg; y_cast = ay + (by - ay) * a_seg; } else if (a_seg < 0) { x_cast = ax; y_cast = ay; } else if (a_seg > 1) { x_cast = bx; y_cast = by; } } }
public void recordAddFeature(PolylineFeature feature) { featuresContainer.addFeature(feature); // make feature attached undoElementCurrent.addFeature(feature); redoElements.Clear(); }
public void addFeature(PolylineFeature feature) { UndoElementPrimitive elem = new UndoElementPrimitive(); elem.featureAdded(feature); undoPrimitives.Add(elem); }
public void featureAdded(PolylineFeature feature) { operationType = UndoElementType.InsertFeature; this.featureIndex = feature.FeatureID; }
public override void KeyDown(object sender, KeyEventArgs e) { base.KeyDown(sender, e); // delete selected features and points if (e.KeyCode == Keys.Delete) { // delete selected points, split polyline into two where applicable // start recording undo step polylineLayer.Manager.startRecordingUndoElement(); symbolLayer.Manager.startRecordingUndoElement(); int count = polylineLayer.FeaturesCount; for (int iFeature = count - 1; iFeature >= 0; iFeature--) { Feature feature = polylineLayer.FeatureGet(iFeature); if (feature == null) continue; if (feature.Selected) { // remove this polyliline and all related symbols PolylineFeature poly = (PolylineFeature)feature; for (int iPart = 0; iPart < poly.m_oParts.Count; iPart++) { Part part = poly.m_oParts[iPart]; for (int iPoint = 0; iPoint < part.Points.Count; iPoint++) { DPoint point = part.Points[iPoint]; symbolLayer.Manager.recordRemoveFeature((SymbolFeature)point.Tag); } } polylineLayer.Manager.recordRemoveFeature((PolylineFeature)feature); } else { // building points of polyline // select polyline points if (feature is PolylineFeature) { PolylineFeature oP = (PolylineFeature)feature; // if this polyline has selected point(s), it will be split // calculate number of new polylines int newPolylines = 0; int partCount = oP.m_oParts.Count; for (int iPart = partCount - 1; iPart >= 0; iPart--) { List<DPoint> points = oP.m_oParts[iPart].Points; int pointCount = points.Count; for (int iPoint = 1; iPoint < pointCount; iPoint++) { if (iPoint == 1) { newPolylines = (points[0].Selected ? 0 : 1); } if (points[iPoint - 1].Selected == true && points[iPoint].Selected == false) { newPolylines++; } } } if (newPolylines < 2) { // just modify existing polyline int partCount1 = oP.m_oParts.Count; for (int iPart = partCount1 - 1; iPart >= 0; iPart--) { List<DPoint> points = oP.m_oParts[iPart].Points; int pointCount = points.Count; for (int iPoint = pointCount - 1; iPoint >= 0; iPoint--) { if (points[iPoint].Selected) { symbolLayer.Manager.recordRemoveFeature((SymbolFeature)points[iPoint].Tag); polylineLayer.Manager.recordRemovePoint(iFeature, iPart, iPoint); } } if (points.Count == 0) { polylineLayer.Manager.recordRemovePart(iFeature, iPart); } } if (oP.m_oParts.Count == 0) { polylineLayer.Manager.recordRemoveFeature((PolylineFeature)feature); } } else { // add new polyline(s), delete original PolylineFeature featureNew = null; List<DPoint> newPoints = null; // draw polyline points int partCount1 = oP.m_oParts.Count; for (int iPart = partCount1 - 1; iPart >= 0; iPart--) { List<DPoint> points = oP.m_oParts[iPart].Points; int pointCount = points.Count; for (int iPoint = 0; iPoint < pointCount; iPoint++) { if (points[iPoint].Selected) { if (newPoints != null) { featureNew = new PolylineFeature(newPoints, feature.Style); polylineLayer.Manager.recordAddFeature(featureNew); featureNew = null; newPoints = null; } symbolLayer.Manager.recordRemoveFeature((SymbolFeature)points[iPoint].Tag); } else { if (newPoints == null) newPoints = new List<DPoint>(); newPoints.Add((DPoint)points[iPoint].Clone()); } } } if (newPoints != null) { featureNew = new PolylineFeature(newPoints, feature.Style); polylineLayer.Manager.recordAddFeature(featureNew); featureNew = null; newPoints = null; } polylineLayer.Manager.recordRemoveFeature(feature); } } } } // finish recording undo step polylineLayer.Manager.stopRecordingUndoElement(); symbolLayer.Manager.stopRecordingUndoElement(); // emit event ToolUsed(this, new EventArgs()); } // clear selection MapControl.Globals.Instance.MapControl.InvalidateMap(); }