ThinkGeo.com    |     Documentation    |     Premium Support

Ruler Overlay Project

Hi Ben, 



There is small change between Wpf Desktop and Desktop; the attached file is the interactive overlay for WpfDesktop. Please have a try and let me know if you have more queries.



Thanks,

Howard



RulerTrackInteractiveOverlay.txt (4.46 KB)

Many thanks for your answer,



I used the new class, but the DrawCore function return the below error:

The decimal degree longitude value you provided was out of range.

Parameter name: fromLongitude




I attache a sample project for you.



Regards,

Ben 



Distance.zip (62.9 KB)

I think that you will get this error if your latitude or longitude is outside of the valid range based on your map unit.  For example, if your map unit is set to DecimalDegrees and you get a longitude greater than 180 or less than -180, you get this error.  I may be wrong but i recall running into this problem.  



Hi Ben,



I absolutely agree with Klaus that measure a distance outside of the bounding box in decimal degree is invalid. We also did some research on the Global Mapper which cannot measure the distance outside of the bounding box neither. I have two options for you. The first one is to catch the exception and set the distance value to invalid string such as "Invalid distance". For the other option is that use projection to re-project from EPSG:4326 to EPSG:4326. In the interactive overlay class, please replace the following method.

protected override void DrawCore(RectangleShape targetExtent, RefreshType refreshType)
{
    if (rulerLineShape != null)
    {
        Feature feature = new Feature(rulerLineShape);

        Proj4Projection proj4 = new Proj4Projection();
        proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
        proj4.ExternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
        proj4.Open();
        rulerLineShape = (LineShape)proj4.ConvertToExternalProjection(rulerLineShape);
        proj4.Close();

        double length = rulerLineShape.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Feet);
        feature.ColumnValues.Add("length", ((int)length).ToString() + " feet");
        if (TrackShapeLayer.InternalFeatures.Contains(currentFeatureKey)) TrackShapeLayer.InternalFeatures[currentFeatureKey] = feature;
        else TrackShapeLayer.InternalFeatures.Add(currentFeatureKey, feature);
    }

    base.DrawCore(targetExtent, refreshType);
}

Just let me know if you have more queries.



Thanks,

Howard



Many thanks Howard & Klaus,

It is working perfectly. 



just another question wاats the best way to get rid of it and return to the normal mode. 



Regards, 

Ben



Hi Ben, 



I think the code community didn't consider much such as your requirement. Here is the new version of the interactiveOverlay, you can simply set the TrackMode to None to return to the normal mode.



Let me know if you have more queries.



Thanks,

Howard



001_RulerTrackInteractiveOverlay.cs (5.12 KB)

Many thanks for you answer, 
  
 1-I can not download your file! 
 2-by changing the mode :  wpfMap1.TrackOverlay.TrackMode = TrackMode.None;  the map does not return to the normal mode. 
  
 Regards, 
 Ben

Hi Ben, 



Sorry for the inconvenience, I didn't notice the file suffix affects my uploading; please try this one. 



Thanks,

Howard



001_RulerTrackInteractiveOverlay.txt (5.14 KB)

Howard, any tips on how to modify this interfactive overlay to also measure areas? 



Hi Klaus,


I think the sample in the code community doesn't take any advantage of the TrackInteractiveOverlay, please try this one. You can simply measure line and polygon on your side. Just set TrackMode to polygon to see the area.


Thanks and let me know if you have more queries.


Thanks,

Howard



MeasureTrackInteractiveOverlay.txt (2.79 KB)


Howard, I am having problems with this one.  This all i am doing when in the handler to measure a distance:



 map.TrackOverlay = new MeasureTrackInteractiveOverlay();
 map.TrackOverlay.TrackMode = TrackMode.StraightLine;     

I am noticing a couple of problems: 


1. Ruler does not draw when I right click abd drag.


2. When user draws, a line, it remains on the map after I release the mouse.  It looks like this is default behavior of track onerlay.  I need ruler removed after measure.  


3. When I attempt to draw another line, I get an exception with message "the given key was not found in the dictionary".   


 I sort of get the idea but my tweaks are not working.right.  i am looking at what 

RulerTrackInteractiveOverlay does, to see how I can tweak thi to behave correctly.  If you can please look at the sample again, that would be great, thanks.




Hi Klaus,



I think this overlay have the features you mentioned. For example, you can clear the features when track finished. See my attached sample and let me know how it works.



Thanks,

Howard



001_Distance.zip (11.6 KB)

Howard,


I may be missing something here.  Please execute the attached project to see that the proposed InteractiveOverlay simply throws and exception when i left click and drag across the map.  Am I suppposed to be right clicking and dragging to measure as left click + Drag pans and in some cases throws and exception?


BTW, I had to modify the project as I am using VS 2008 with .NET 3.5 SP1.


Thanks again.


K



Hi Klaus,



I found there are two issues in your code. First of all, I'm not sure why you set the map unit for the map in the click event. If you set it to meter, you need to set the world map kit overlay projection to spherical mercator. The exception you met is from here I think. Secondly, when you add replace the interactive overlay which needs to be draw shapes on it; you need call map.refresh method so that the overlay needs exist in the logic tree. So here we ignore the issue of the map unit, here is the code for the click event. 

MeasureTrackInteractiveOverlay rulerTrackInteractiveOverlay = new MeasureTrackInteractiveOverlay();
rulerTrackInteractiveOverlay.TrackEnded += (o, a) => { rulerTrackInteractiveOverlay.TrackShapeLayer.InternalFeatures.Clear(); };
wpfMap1.TrackOverlay = rulerTrackInteractiveOverlay;
wpfMap1.TrackOverlay.TrackMode = TrackMode.StraightLine;
wpfMap1.Refresh();



Thanks,

Howard



Good man. Works wonderfully.    The first issue with unit was a copy paste thing.  Was not thinking there. 


Hey, thanks again.


K



You are welcome. And please, do not hesitate to let us know if you have any other concerns/ideas.

Is there a way to use the measuretrack overlay with multiple points?  I envision setting the map to "measure mode" and every time the user left clicks on the map, a new point is added and the distance from the last point to the newest point is added to the total distance.  Right-clicking on the map would clear the measurement.

 Hi Thomas,


 
I do not quite understand the requirement. Do you want to change the style of the solid line to dot? If yes, it can be implement by setting the line style on the TrackLayer on the TrackOverlay. Here is the code using dash pattern on the line style.

LineStyle lineStyle = new LineStyle();
lineStyle.OuterPen.Color = GeoColor.StandardColors.Red;
lineStyle.OuterPen.Width = 4;
lineStyle.OuterPen.DashStyle = LineDashStyle.Dot;
lineStyle.OuterPen.DashPattern.Add(1);
lineStyle.OuterPen.DashPattern.Add(2);

 
And here is the screenshot.

Please let me know if there is any misunderstanding.
 
Thanks,
Howard

 What I am trying to do is add several points to the overlay and have the distance calculated from one point to the next.  I want to provide the sum of those distances to the user.  So the visual would still be a line, but on every click, you would add an additional vertex.



Hi Thomas,



I think this can be done by hooking some events on the TrackOverlay. Please copy the attached file to our HowDoISamples/CSharp Samples/Editing Feature Layers/ folder and modify the extension of the file to .cs. It might be the way you want. 



Please let me know if there is any misunderstanding.



Thanks,

Howard



TrackAndEditShapes.xaml.txt (5.38 KB)