Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I know that copy a question is not exactly great way to ask on this forum, but my situation is exactly the same as this unresolved issue on the (closed) ESRI forum:

I have a stream centreline (fairly curvy) which can be converted to a route. I have a few points on that line which have stream bed elevation. The bed elevation varies along the stream, and does not necessarily increase as you go up the stream (e.g., goes up and down a little bit).

I want to calibrate the route using the bed elevations, so that I can interpolate an elevation value between the known points.

When I attempt to calibrate the stream route with the known points, it appears to work. But if I examine the measure values of individual vertices along the route, they are incorrect. Vertices that fall exactly where there is a known value (a calibration point) have the correct elevation, but vertices between the known points have incorrect values. The incorrect values are not 0, which makes me think it is calculating a value somehow. But it is not doing as I expect.

For example, between known points of 3.11 and 3.56, you'd expect values between 3.11 and 3.56. Instead, I might get values of 3.78, 3.78, 3.78, 3.79, etc.

May be it can be resolved in here.

Best regards Tomek

share|improve this question
    
Instead of using M's, have you considered creating a TIN from you calibration points, then calling ISurface.InterpolateShapeVertices? –  Kirk Kuykendall Sep 21 '11 at 20:08
add comment

2 Answers

up vote 3 down vote accepted

It looks to me like there's a bug in IMSegmentation3.CalibrateByMs for v10.0 sp2. When I create a diagonal polyline from 0.0,0.0 to 10.0,10.0 with unknown measures at its vertices, then calibrate it, I would expect to see all vertices have measures - not just the ones inserted.

Update

Oops, I had forgot to call CalculateNonSimpleMs, after adding it, I get this output. I would expect to see a measure of 100.0 at 10.0,10.0 - not 62.5. I think this is a bug.

split 2.5,2.5,100.0
split 5.0,5.0,50.0
split 7.5,7.5,75.0
0.0,0.0,112.5 (BUG)
2.5,2.5,100.0
5.0,5.0,50.0
6.0,6.0,60.0 (CORRECT)
7.5,7.5,75.0
10.0,10.0,62.5 (BUG)
Measure at 0.55 is 55.00000001234

Here's the c# code:

public static void TestPolylineM(ISpatialReference sr)
{    
    var calibrationPts = new MultipointClass() as IPointCollection;
    ((IMAware)calibrationPts).MAware = true;
    ((IGeometry)calibrationPts).SpatialReference = sr;

    //                                  x    y    m
    calibrationPts.AddPoint(MakePointM(2.5, 2.5, 100.0, sr));
    calibrationPts.AddPoint(MakePointM(5.0, 5.0, 50.0, sr));
    calibrationPts.AddPoint(MakePointM(7.5, 7.5, 75.0, sr));

    IPointCollection pc = new PolylineClass();
    ((IGeometry)pc).SpatialReference = sr;
    ((IMAware)pc).MAware = true;
    pc.AddPoint(MakePointM(0.0, 0.0, double.NaN, sr));
    pc.AddPoint(MakePointM(6.0, 6.0, double.NaN, sr));
    pc.AddPoint(MakePointM(10.0, 10.0, double.NaN, sr));

    var mseg = pc as IMSegmentation3;

    int how = (int) (esriGeometryUpdateMEnum.esriGeometryInterpolate 
        | esriGeometryUpdateMEnum.esriGeometryExtrapolateAfter 
        | esriGeometryUpdateMEnum.esriGeometryExtrapolateBefore);

    Simplify((IGeometry)pc);
    double cutoffDistance = 1.0;

    var splitPoints = mseg.CalibrateByMs(calibrationPts.EnumVertices, how, cutoffDistance);
    mseg.CalculateNonSimpleMs();
    ListSplits(splitPoints);


    for (int i = 0; i < pc.PointCount; i++)
    {
        var pnt = pc.get_Point(i);
        Debug.Print("{0:0.0},{1:0.0},{2:0.0}", pnt.X, pnt.Y, pnt.M);
    }

    double distAlong = 0.55;
    var measures = mseg.GetMsAtDistance(distAlong, true) as double[];
    Debug.Print("Measure at {0} is {1}", distAlong, measures[0]);
}

public static IPoint MakePointM(double x, double y,double m, ISpatialReference sr)
{
    IPoint pnt = new PointClass();
    ((IMAware)pnt).MAware = true;
    pnt.SpatialReference = sr;
    pnt.PutCoords(x, y);
    if(!Double.IsNaN(m))
        pnt.M = m;
    return pnt;
}

public static void ListSplits(IEnumSplitPoint splitPoints)
{
    IPoint splitPoint;
    int partIndex;
    int vertexIndex;
    splitPoints.Next(out splitPoint, out partIndex, out vertexIndex);
    while (splitPoint != null)
    {
        Debug.Print("split {0:0.0},{1:0.0},{2:0.0}", splitPoint.X, splitPoint.Y, splitPoint.M);
        splitPoints.Next(out splitPoint, out partIndex, out vertexIndex);
    }

}
public static void Simplify(IGeometry geom)
{
    var topoOp = geom as ITopologicalOperator2;
    if (topoOp != null)
    {
        topoOp.IsKnownSimple_2 = false;
        topoOp.Simplify();
    }
}
share|improve this answer
    
Ok, so there is a bug. Thanks, though I was hoping that I am doing something wrong... Probably this would be a lot easier to fix. Is there any way to get work properly? Or is there alternative to perform such task? Thanks for your work Kirk, for me realy impressive. –  Tomek Sep 21 '11 at 18:42
    
@Tomek Did you keep an older version of ArcGIS around? :-) –  whuber Sep 21 '11 at 18:44
    
Given a streams layer and a calibration points layer, I think it would be possible to create correct M values on the line layer. It looks like the CalibrateMs is correctly interpolating but not extrapolating. That means you should be able to go through each polyline and extrapolate. The problem I see though is, suppose you have a fork in a river with no calibration point. The M for the endpoints of each polyline would get extrapolated to different values, making it appear there are waterfalls. Maybe these nodes could be identifed using a topology and then averaged. –  Kirk Kuykendall Sep 21 '11 at 19:17
    
@Whuber Yes, I do have 9.3.1 as well, as 10 gives me a hard time with some task. However, the problem does occurs earlier as well. If you take a look at ESRI closed question, you'll notice that Sarah did have this problem in 2008 already. Also I tried calibration tool on 9.3.1 and 10.0 sp1. No luck. I read that in QGIS is available PostGIS plugin for linear referencing. I'll give it a shot. –  Tomek Sep 21 '11 at 19:41
    
@Kirk, thanks for advice. I'll give it a shot as well. Thanks a million. –  Tomek Sep 21 '11 at 19:42
show 1 more comment

This is a bug, it's been causing me problems for years. And yes, there is a workaround -- but a tedious one. I've been in touch with ESRI Canada about this, they replicated the bug, and have told me that Esri US is working on it... I'm not sure if that means a fix for 10.1 or later. Bug is NIM069049 (you can search for that on Esri's web site, but it doesn't give you much info). The bug applies to the Calibrate Routes tool. I get it when I'm working with stream bed elevations or water surface elevations -- values that don't necessarily always increase or decrease along the line, and that are not related to the line length. I don't have problems with the Calibrate Routes tool for values that are related to line length, such as calculating chainage (mileposts). A workaround is to do the calibration manually. Manual calibration takes a lot longer than using the Calibrate Routes tool, but it does work. If you don't know how to calibrate manually, there's a tutorial. At 9.3, the link is: http://webhelp.esri.com/arcgisdesktop/9.3/pdf/linear_referencing_tutorial.pdf For 10, the link is: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Exercise_5_Editing_routes/00390000004p000000/ Checkout the last section, Recalibrating a Route.

share|improve this answer
    
Thanks Sarah. I do have plenty of long polylines to calibrate, so manual way isn't really an option. When I'll find solution that works, I'll let you know. –  Tomek Sep 22 '11 at 11:33
    
Hi Sarah--thanks for answering. Nice to see you here! –  whuber Sep 22 '11 at 15:13
    
Hi Bill -- Thanks for suggesting the site (on gislist)! –  Sarah North Sep 22 '11 at 15:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.