ThinkGeo.com    |     Blog    |     Wiki    |     Support

How to plotting the point and display distance between two point

Hi Fathin,

That’s great, so we can modify based on the sample and save our communication time.

Just like I mentioned, it should be simple enough and shows the problem clearly, I think our template is a good choice for create a sample quickly: http://wiki.thinkgeo.com/wiki/map_suite_project_template_guide

Regards,

Ethan

Hi Ethan

This is a sample i just construct. I managed to plot the map using InMemoryFeatureLayer. I have this problem:

  1. Adjust the icon with the tooltip of mouse.
  2. How can implement button for the InMemoryFeatureLayer to enabled it, so when i start the run the it not immediately execute the InMemoryFeatureLayer for plot.
  3. How can i delete the specific plot.

My code below throw me an exception:

KeyNotFoundException was unhandled

with remarks :

The given key was not present in the dictionary.

CODE:

 namespace PointPlot
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        InMemoryFeatureLayer inmemoryFeatureLayer = new InMemoryFeatureLayer();
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Map1_Loaded(object sender, RoutedEventArgs e)
        {
            Map1.MapUnit = GeographyUnit.Meter;
            LayerOverlay myOverlay = new LayerOverlay();
            Map1.Overlays.Add(myOverlay);

            myOverlay.TileCache = new FileBitmapTileCache(@"C:\Users\User\Documents\Visual Studio 2012\Projects\RasterMapViewer\RasterMapViewer\Cache\");

            string[] files = System.IO.Directory.GetFiles(@"C:\Users\User\Desktop\DSI REFERENCE\Map Data\Raster");

            foreach (string file in files)
            {
                GeoTiffRasterLayer tiffLayer = new GeoTiffRasterLayer(file);

                myOverlay.Layers.Add(tiffLayer);
            }
            myOverlay.Open();
            Map1.CurrentExtent = myOverlay.GetBoundingBox();

            InMemoryFeatureLayer inmemoryFeatureLayer = new InMemoryFeatureLayer();
            inmemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(@"C:\Users\User\Documents\Visual Studio 2012\Projects\PointPlot\PointPlot\Icon\Point.png"));
            //inmemoryFeatureLayer.InternalFeatures.Add("point", new Feature(@"C:\Users\User\Documents\Visual Studio 2012\Projects\PointPlot\PointPlot\Icon\Point.png"));           
           
            inmemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay markerOverlay = new LayerOverlay();
            markerOverlay.Layers.Add(inmemoryFeatureLayer);
            Map1.Overlays.Add("MarkerOverlay", markerOverlay);
           
            Map1.Overlays.Add("MarkerOverlay", markerOverlay);

          
            Map1.Refresh();

        }

        private void Map1_MapClick(object sender, MapClickWpfMapEventArgs e)
        {
            
            LayerOverlay markerOverlay = (LayerOverlay)Map1.Overlays["MarkerOverlay"];
            InMemoryFeatureLayer inmemoryFeatureLayer = markerOverlay.Layers[0] as InMemoryFeatureLayer;

            MultipolygonShape buffer = e.WorldLocation.Buffer(350, GeographyUnit.Meter, DistanceUnit.Kilometer);

                inmemoryFeatureLayer.InternalFeatures.Add(new Feature(e.WorldLocation));

            //Collection<Feature> deleteMarkers = inmemoryFeatureLayer.QueryTools.GetFeaturesWithin(buffer, ReturningColumnsType.NoColumns);
            //if (deleteMarkers.Count > 0)
            //{
            //    inmemoryFeatureLayer.InternalFeatures.Remove(deleteMarkers[0]);
            //}
            //else
            //{
            //    inmemoryFeatureLayer.InternalFeatures.Add(new Feature(e.WorldLocation));
            //}

           Map1.Refresh();
        }

        private void Plot_ButtonClick(object sender, RoutedEventArgs e)
        {
            InMemoryFeatureLayer inMemoryLayer = (InMemoryFeatureLayer)Map1.FindFeatureLayer("InMemoryFeatureLayer");

            inMemoryLayer.Open();
            inMemoryLayer.EditTools.BeginTransaction();
            inMemoryLayer.EditTools.Delete("MarkerOverlay");
            inMemoryLayer.EditTools.CommitTransaction();
            inMemoryLayer.Close();

            Map1.Refresh(Map1.Overlays["InmemoryOverlay"]);   
        }
    }
}

Regards,

Fathin

Hi Ethan,

If let say i create a point using marker just like in HowDoI sample, is that any a way for me to select the point so that i can edit the point or maybe get a distance in line from one marker point to another>

Regards,

Fathin

Hi Fathin,

  1. Adjust the icon with the tooltip of mouse.
    I hadn’t notice your code have related logic, do you means change the mouse cursor? or the tooltip of marker which is clicked by mouse?

  2. How can implement button for the InMemoryFeatureLayer to enabled it, so when i start the run the it not immediately execute the InMemoryFeatureLayer for plot.
    Add a bool type variable, set it’s value by a button. If it’s true just return in Map1_MapClick event, if it’s false, run your logic.

  3. How can i delete the specific plot.

This logic should be helpful.

            Collection<Feature> neartestFeatures = inmemoryFeatureLayer.QueryTools.GetFeaturesNearestTo(e.WorldLocation, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns);
        if (neartestFeatures.Count > 0)
        {
            inmemoryFeatureLayer.InternalFeatures.Remove(neartestFeatures[0]);
        }
  1. is that any a way for me to select the point so that i can edit the point or maybe get a distance in line from one marker point to another
    Use the query logic for item 3, then add the point into a special layer, you can call it highlight layer. It can be thought selected point. You can make this layer contains two points, then create a line between them(start point and end point), then show the line.

Here is a sample project based on your code, please modify based on it, and you can upload it again to show your question instead of paste code.

15floors.zip (11.7 KB)

Regards,

Ethan

Hi Ethan,

Sorry for not clear statement regarding question (1). I mean how can i adjust so that the tooltip of icon near the tooltip of mouse cursor. Just like in using SimpleMarkerOverlay by adjusting the Yoffset, but i need to implement it on InMemoryFeatureLayer.

Sorry for paste the code i will modify the sample and upload it if i have issues with it.

Regards,

Fathin

Hi Fathin,

That related with how you implement the tooltip. I think our InmemoryFeatureLayer don’t support tooltip by default, it’s not the same like MarkerOverlay.

If you still hadn’t found the way to implement that, please refer this topic: OpenStreet Maps and WGS84 map

It contains a custom tooltip which works for winform, but I think you can try to use it in WPF and see whether it works for your requirement.

Regards,

Ethan

HI Ethan,

May i know how can i make a selection for the inmemoryfeaturelayer? What i mean i can select the point that just been created using InmemoryFeatureLayer. In addition, can you check this code? I try copy exactly the same code from HowDoI sample for delete the feature in InmemoryFeatureLayer. It does not delete the rectangle feature.

Regards,

Fathin

Hi Fathin,

Thanks for your code.

The “Rectangle” is key of feature but not its id, so the code should looks like:

            inMemoryLayer.Open();
        inMemoryLayer.EditTools.BeginTransaction();
        inMemoryLayer.EditTools.Delete(inMemoryLayer.InternalFeatures["Rectangle"].Id);
        inMemoryLayer.EditTools.CommitTransaction();
        inMemoryLayer.Close();

And if you upload the sample, you don’t need package the “packages” and “bin” and “obj” folders.

Regards,

Ethan

Hi Ethan,

May i know what i got it wrong, i can seem to perform the delete function for InmemoryFeatureLayer. It throw :

ArgumentException was unhandled

remarks

An item with the same key has already been added.

15floors.zip (13.3 KB)

Regards,

Fathin

Hi Fathin,

Please comment this line: Map1.MapClick+=Map1_MapClick;

You bind the event twice, so the same feature with same key “woi” is added twice.

Regards,

Ethan

Hi Ethan,

i already comment the line you mention. But how can i bind the Feature to button click? I try to use the id “woi” so that it can bind the:

inmemoryFeatureLayer.EditTools.Delete(inmemoryFeatureLayer.InternalFeatures[“woi”].Id);

to

inmemoryFeatureLayer.InternalFeatures.Add(“woi”,new Feature(e.WorldLocation));

but it still throw :

ArgumentException was unhandled

remarks

An item with the same key has already been added.

 private void Map1_MapClick(object sender, MapClickWpfMapEventArgs e)
    {
        _LastMapClickLocation = e.WorldLocation;
        LayerOverlay markerOverlay = (LayerOverlay)Map1.Overlays["MarkerOverlay"];
        InMemoryFeatureLayer inmemoryFeatureLayer = markerOverlay.Layers[0] as InMemoryFeatureLayer;
        
        MultipolygonShape buffer = e.WorldLocation.Buffer(350, GeographyUnit.Meter, DistanceUnit.Kilometer);

        inmemoryFeatureLayer.InternalFeatures.Add("woi",new Feature(e.WorldLocation));

        Map1.Refresh();
    }

    private void Plot_ButtonClick(object sender, RoutedEventArgs e)
    {
        inmemoryFeatureLayer.Open();
        inmemoryFeatureLayer.EditTools.BeginTransaction();
        inmemoryFeatureLayer.EditTools.Delete(inmemoryFeatureLayer.InternalFeatures["woi"].Id);
        inmemoryFeatureLayer.EditTools.CommitTransaction();
        inmemoryFeatureLayer.Close();
    }

Regards,

Fathin.

Hi Fathin,

I thought you want to delete the “woi” feature when you click the button.

But it looks you don’t want to delete specified feature.

In your logic, each time you click on map the Map1_MapClick will be fired and a new feature with same key “woi” will be added, that’s why you met the same exception.

Please let me know your delete logic, what’s your target here.

For example: you want to delete a feature in clicked point.

I want to know your delete scenario, so I can help you complete the logic here.

Regards,

Ethan

Hai Ethan,

Actually my logic for now , it just to delete the feature or i mean to clear all the feature that i just created by Map1_MapClick function.

Regards,

Fathin

Hi Fathin,

If your target is clear all features, that’s easy.

    inmemoryFeatureLayer.InternalFeatures.Add(new Feature(e.WorldLocation)); // Don't set key here





    private void Plot_ButtonClick(object sender, RoutedEventArgs e)
    {
        LayerOverlay markerOverlay = (LayerOverlay)Map1.Overlays["MarkerOverlay"];
        InMemoryFeatureLayer inmemoryFeatureLayer = markerOverlay.Layers[0] as InMemoryFeatureLayer;
        inmemoryFeatureLayer.Clear();

        Map1.Refresh();
   }

Wish that’s helpful.

Regards,

Ethan

Hi Ethan,

I try to use below code to select the marker that created using InmemoryFeatureLayer, so that i can delete the specific marker. I put the below code on the button click event, so that when i click it fire the mapclick event to select the marker and delete that marker. The problem is that is not successfull, the event does not fire instead it still create the new marker when i click on specific marker that i want to delete.

Collection neartestFeatures = inmemoryFeatureLayer.QueryTools.GetFeaturesNearestTo(e.WorldLocation, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns);
if (neartestFeatures.Count > 0)
{
inmemoryFeatureLayer.InternalFeatures.Remove(neartestFeatures[0]);
}

15floors.zip (14.6 KB)

Regards,

Fathin

Hi Fathin,

Your logic have problem, our GetFeaturesNearestTo return max to 10 features in your logic, but it’s not always equal 10.

For example, when I run it, the return features equal 6.

So your logic should looks like:
inmemoryFeatureLayer.InternalFeatures.Remove(neartestFeatures[neartestFeatures.Count - 1]);

And you bind the MapClick event multiply times, please view the modified sample here:
9408_27.zip (14.6 KB)

For make it works, I comment your path, you can modify it back.

Regards,

Ethan

HI Ethan,

Thank you it work. Then i need to select the specific marker that created by inememoryfeaturelayer to get the distance between 2 point. Did i need to make a new layer for it just for calculating the distance?

Regards,

Fathin

Hi Fathin,

You can create a new layer to save the result, that’s simpler, or you can directly add the line in currently layer, don’t forget assign line style, but if you have other line shape in the same layer, we don’t suggest you do it.

Regards,

Ethan

HI Ethan,

What the new layer that i need to create, it a inmemoryfeaturelayer or inmemorymarkeroverlay? Still need to apply the trackoverlay function for this new layer right to create line between two point?

Regards,

Ethan

Hi Fathin,

I think an inmemoryfeaturelayer is enough for your scenario, you can add it in the same overlay.

And I suggest you view our HowDoISamples, it contains many general scenario, it should be helpful for your project.

Regards,

Ethan