ThinkGeo.com    |     Documentation    |     Premium Support

GetLineOnALine(PointShape,PointShape) adds duplicate point at end of new line

I am splitting a selected multiline shape on a click point.  The second line of the split ends up with a duplicate point at the end.


I have proj4 code as I have a GoogleMapOverlay and my shapefile in the same map.


MultilineShape lineshape2 = (MultilineShape)(selectedFeaturesR[d].GetShape());

Collection<LineShape> lines = lineshape2.Lines;

LineShape lineshape = lines[0]; 

Collection<Vertex>pointss = lineshape.Vertices;

PointShape startpoint = new PointShape(pointss[0].X, pointss[0].Y);

lineshape = lines[lines.Count - 1]; 

pointss = lineshape.Vertices;

PointShape endpoint = new PointShape(pointss[pointss.Count - 1].X, pointss[pointss.Count - 1].Y);

startdistance = worldPoint.GetDistanceTo(startpoint, winformsMap1.MapUnit, DistanceUnit.Meter);



PointShape newpoint = lineshape2.GetPointOnALine(StartingPoint.FirstPoint, startdistance,winformsMap1.MapUnit, DistanceUnit.Meter);

if (newpoint != null)

{

    Vertex projVertexA = proj4.ConvertToInternalProjection(newpoint.X, newpoint.Y);

    int totverts = 0; distance = 999999999.99999F; tmppos = -1; mpos = -1;

    for (int p = 0; p < lines.Count; p++)

    {

        totverts = totverts + lines[p].Vertices.Count;

        for (int h = 0; h < lines[p].Vertices.Count; h++)

        {

            double tmpdist = newpoint.GetDistanceTo(new PointShape(lines[p].Vertices[h].X, lines[p].Vertices[h].Y), winformsMap1.MapUnit, DistanceUnit.Meter);

            if (tmpdist < distance) { distance = tmpdist; mpos = p; tmppos = h; }

        }

    }

    if (distance < tolerance) { newpoint = new PointShape(lines[d].Vertices[tmppos].X, lines[mpos].Vertices[tmppos].Y); }

    projVertexA = proj4.ConvertToInternalProjection(newpoint.X, newpoint.Y);



    nextid++;

    values["UNIQ"] = "DTI" + nextid.ToString();

    MultilineShape newshape1 = (MultilineShape)lineshape2.GetLineOnALine(startpoint, newpoint);

    int vertcount1 = 0; lines = newshape1.Lines;

    for (int p = 0; p < lines.Count; p++) { vertcount1 = vertcount1 + lines[p].Vertices.Count; }

    roadsLayer.EditTools.BeginTransaction();

    roadsLayer.EditTools.Add(newshape1, values);

    roadsLayer.EditTools.CommitTransaction();



    nextid++;

    MultilineShape newshape2 = (MultilineShape)lineshape2.GetLineOnALine(newpoint,endpoint);

    int vertcount2 = 0; lines = newshape2.Lines;

    for (int p = 0; p < lines.Count; p++) { vertcount2 = vertcount2 + lines[p].Vertices.Count; }

    values["UNIQ"] = "DTI" + nextid.ToString();

    roadsLayer.EditTools.BeginTransaction();

    roadsLayer.EditTools.Add(newshape2, values);

    roadsLayer.EditTools.CommitTransaction();



    roadsLayer.EditTools.BeginTransaction();

    roadsLayer.EditTools.Delete(selectedFeaturesR[d].Id);

    roadsLayer.EditTools.CommitTransaction();



    roadsLayer.Close();

    ShapeFileFeatureLayer.Rebuild(shapedir + "\\" + roadfile);

    roadsLayer.Open();

}

 


I have had to add the following to remove the extra vertice.


    int vertcount1 = 0; lines = newshape1.Lines;

    for (int p = 0; p < lines.Count; p++)

    {

        Vertex vert1 = lines[p].Vertices[0];

        for (int h = 1; h < lines[p].Vertices.Count; h++)

        {

            if ((vert1.X == lines[p].Vertices[h].X) && (vert1.Y == lines[p].Vertices[h].Y))

            {

                lines[p].Vertices.Remove(vert1);

                break;

            }

            vert1 = lines[p].Vertices[h];

        }

    }

 


Is this an bug in the GetLineOnALine or am I doing something wrong in  code. 


Elisa



It could be a bug. To verify this, could you send us the WKT definition of the MultiLineShape you do the GetLineOnLine? Also, give us the X and Y values of the points you are using for that. Thank you.

It could be a bug. To verify this, could you send us the WKT definition of the MultiLineShape you do the GetLineOnLine? Also, give us the X and Y values of the points you are using for that. Thank you.

These are the coordinates for the original line: 
 -110.5401246,53.3934808 
 -110.539955,53.39526 
  
 The split point is: 
 -110.540034308832,53.394428014715 
  
 These are the coordinates for the first line from the split: 
 -110.5401246,53.3934808 
 -110.540034308832,53.394428014715 
  
 These are the coordinates for the second line from the split: 
 -110.540034308832,53.394428014715 
 -110.539955,53.39526 
 -110.539955,53.39526 
  
 I don’t understand what you mean by WKT.  If you are referring to the information in the API documentation, see below: 
  
 C#    
 public LineBaseShape GetLineOnALine(  
    PointShape startPointShape, 
    PointShape endPointShape 
 ) 
   
 Parameters 
 startPointShape  
 The startPointShape defines where you will start to get the line. If it does not stand on this MultilineShape, the closest point on the MultilineShape will be the start PointShape.  
 endPointShape  
 The endPointShape defines where you will stop getting the line. If it does not stand on this MultilineShape, the closest point on the MultilineShape will be the end PointShape.  
  
 Return Value 
 This method returns a BaseLineShape based on a start PointShape and an end PointShape.  
  
 Exceptions 
 Exception Description  
 ArgumentNullException Passing a null startPointShape will throw an ArgumentNullException.  
 ArgumentNullException Passing a null endPointShape will throw an ArgumentNullException.  
 InvalidOperationException In the event you attempt to call this method on a shape which has less than two points, it will throw an InvalidOperationException.  
  
 Thanks. 
  
 Elisa

WKT stands for Well Known Text, it is a standard for specifying geometric shapes and all the shapes in Map Suite have the GetWellKnownText method.


 I tried the GetLineOnLine with the coordinates you sent us and I get correct results


With FirstPoint:



 


With LastPoint:



And this is the code I used according to what you send me in your last post. I cannot reproduce the problem.


 



LineShape lineShape = new LineShape();
lineShape.Vertices.Add(new Vertex(-110.5401246,53.3934808));
lineShape.Vertices.Add(new Vertex(-110.539955,53.39526));

PointShape pointShape = new PointShape(-110.540034308832, 53.394428014715);

//LineShape subLineShape = (LineShape)lineShape.GetLineOnALine(StartingPoint.FirstPoint, pointShape);
LineShape subLineShape = (LineShape)lineShape.GetLineOnALine(StartingPoint.LastPoint, pointShape);

InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Circle, GeoColor.StandardColors.DarkBlue, 12);
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Green, 8, true);
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryFeatureLayer.InternalFeatures.Add(new Feature(lineShape));
inMemoryFeatureLayer.InternalFeatures.Add(new Feature(pointShape));

InMemoryFeatureLayer inMemoryFeatureLayer2 = new InMemoryFeatureLayer();
inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Red, 3, true);
inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryFeatureLayer2.InternalFeatures.Add(new Feature(subLineShape));


LayerOverlay dynamicOverlay = new LayerOverlay();
dynamicOverlay.Layers.Add(inMemoryFeatureLayer);
dynamicOverlay.Layers.Add(inMemoryFeatureLayer2);
winformsMap1.Overlays.Add(dynamicOverlay);

inMemoryFeatureLayer.Open();
winformsMap1.CurrentExtent = new RectangleShape(-110.5421, 53.3956, -110.5377, 53.3931);
inMemoryFeatureLayer.Close();

winformsMap1.Refresh();




Also the result from subLineShape.Vertices.Count is 2 as expected. Please, tell us how to reproduce your problem. Thank you.



 



Val: 
 Your code uses: 
 LineShape subLineShape = (LineShape)lineShape.GetLineOnALine(StartingPoint.LastPoint, pointShape); 
  
 My code uses: 
 MultilineShape newshape2 = (MultilineShape)lineshape2.GetLineOnALine(newpoint,endpoint); 
  
 I had no problem with the code in your sample.  It is with the function in my code that causes the issue. 
 Again, my shapefile is in lat,lng that has to be projected to match GoogleMapsOverlay.  I don’t know if  
 this is part of the problem or not. 
  
 Elisa

I changed the code to have it working with a MultiLineShape as you can see below. And this is working fine. In your previous post, you give us the X and Y value of the split point but you don't give us the values for newpoint and endpoint.


My code uses: 

MultilineShape newshape2 = (MultilineShape)lineshape2.GetLineOnALine(newpoint,endpoint); 

 


 



winformsMap1.MapUnit = GeographyUnit.DecimalDegree;

MultilineShape multiLineshape = new MultilineShape();
LineShape lineShape = new LineShape();
lineShape.Vertices.Add(new Vertex(-110.5401246, 53.3934808));
lineShape.Vertices.Add(new Vertex(-110.539955, 53.39526));
multiLineshape.Lines.Add(lineShape);

PointShape pointShape = new PointShape(-110.540034308832, 53.394428014715);

//MultilineShape subMultilineShape = (MultilineShape)multiLineshape.GetLineOnALine(StartingPoint.FirstPoint, pointShape);
MultilineShape subMultilineShape = (MultilineShape)multiLineshape.GetLineOnALine(StartingPoint.FirstPoint, pointShape);

InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Circle, GeoColor.StandardColors.DarkBlue, 12);
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Green, 8, true);
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryFeatureLayer.InternalFeatures.Add(new Feature(multiLineshape));
inMemoryFeatureLayer.InternalFeatures.Add(new Feature(pointShape));

InMemoryFeatureLayer inMemoryFeatureLayer2 = new InMemoryFeatureLayer();
inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Red, 3, true);
inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryFeatureLayer2.InternalFeatures.Add(new Feature(subMultilineShape));


LayerOverlay dynamicOverlay = new LayerOverlay();
dynamicOverlay.Layers.Add(inMemoryFeatureLayer);
dynamicOverlay.Layers.Add(inMemoryFeatureLayer2);
winformsMap1.Overlays.Add(dynamicOverlay);

inMemoryFeatureLayer.Open();
winformsMap1.CurrentExtent = new RectangleShape(-110.5421, 53.3956, -110.5377, 53.3931);
inMemoryFeatureLayer.Close();

winformsMap1.Refresh();