ZoomToValues.cs

This example demonstrates how to build a list of unique values of the given field and implement zooming to them from the context menu. After the right click on the map a context menu will be displayed with names of the buildings under submenu for each letter of the alphabet. Only the buildings with unique names will be included in the list. After choosing a particular name the extents of the map will be changed to display the corresponding building. Here is a screenshot with the results of the code execution.

ZoomToValues.png
´╗┐using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using AxMapWinGIS;
using MapWinGIS;
using System.Diagnostics;

namespace Examples
{
    public partial class MapExamples
    {
        private ContextMenuStrip _menu = null;  // a menu to be displayed
        private int _fieldIndex = -1;           // the index of the [Name] field
    
        // <summary>
        // Loads layers, builds the lists of unique names for the [Name] field, registers event handler
        // </summary>
        public void ZoomToValues(AxMap axMap1, string dataPath)
        {
            axMap1.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR;

            string filename = dataPath + "buildings.shp";

            if (!File.Exists(filename))
            {
                MessageBox.Show("Couldn't file the file: " + filename);
                return;
            }

            var sf = new Shapefile();
            sf.Open(filename, null);
            m_layerHandle = axMap1.AddLayer(sf, true);
            sf = axMap1.get_Shapefile(m_layerHandle);     // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding

            sf.Labels.Generate("[Name]", tkLabelPositioning.lpCenter, false);
            sf.Labels.TextRenderingHint = tkTextRenderingHint.SystemDefault;

            _fieldIndex = sf.Table.FieldIndexByName["Name"];
            var names = new Dictionary<string, int>();

            for (int i = 0; i < sf.NumShapes; i++)
            {
                string name = (string)sf.Table.CellValue[_fieldIndex, i];
                if (names.ContainsKey(name))
                {
                    names[name]++;
                }
                else
                {
                    names.Add(name, 1);
                }
            }

            IEnumerable<string> list = names.Where(val => val.Value == 1).Select(val => val.Key);
            _menu = new ContextMenuStrip();

            // there can be to much names to show in a single dropdown, 
            // therefore let's add letters of alphabet as the first level of the menu
            string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            for (int i = 0; i < s.Length; i++)
            {
                ToolStripMenuItem item = new ToolStripMenuItem();
                item.Name = s[i].ToString();
                item.Text = s[i].ToString();
                _menu.Items.Add(item);
            }

            // adding names under particular letters
            foreach (string name in list)
            {
                string ch = name[0].ToString();
                foreach (ToolStripMenuItem item in _menu.Items)
                {
                    if (item.Name == ch)
                    {
                        ToolStripMenuItem subItem = new ToolStripMenuItem();
                        subItem.Click += new EventHandler(ItemClick);
                        subItem.Text = name;
                        subItem.Tag = "zoomable";
                        item.DropDownItems.Add(subItem);
                        break;
                    }
                }
            }
        
            // now let's remove the unused letters
            for (int i = _menu.Items.Count - 1; i >= 0; i--)
            {
                ToolStripMenuItem item = _menu.Items[i] as ToolStripMenuItem;
                if (item.DropDownItems.Count == 0)
                    _menu.Items.Remove(item);
            }
       
            axMap1.SendMouseDown = true;
            axMap1.CursorMode = tkCursorMode.cmNone;
            axMap1.MapUnits = tkUnitsOfMeasure.umMeters;
            MapEvents.MouseDownEvent += AxMap1MouseDownEvent4;  // change MapEvents to axMap1
        }

        // <summary>
        // Handles mouse click event. Shows the context menu with the names.
        // </summary>
        private void AxMap1MouseDownEvent4(object sender, _DMapEvents_MouseDownEvent e)
        {
            if (e.button == 2)          // right button
            {
                System.Drawing.Point pnt = axMap1.PointToScreen(new System.Drawing.Point(e.x, e.y));
                _menu.Show(pnt.X, pnt.Y);
            }
        }

        // <summary>
        // Zooms map to the object after user clicks the item on context menu.
        // </summary>
        private void ItemClick(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (sender as ToolStripMenuItem);
            if (item == null) return;
            if (item.Tag.ToString() == "zoomable")
            {
                Shapefile sf = axMap1.get_Shapefile(m_layerHandle);
                if (sf != null)
                {
                    for (int i = 0; i <sf.NumShapes; i++)
                    {
                        string s = sf.get_CellValue(_fieldIndex, i).ToString();
                        Debug.Print(s);
                        if (s == item.Text)
                        {
                            axMap1.ZoomToShape(m_layerHandle, i);
                            axMap1.CurrentScale = 2000;
                            break;
                        }
                    }
                }
            }
        }
    }
}
 All Classes Files Functions Enumerations Properties Events