2014-09-06 3 views
-1

Как сделать следующее: Я не прошу указать конкретный код, но мне нужно какое-то направление, поскольку я долгое время ломаю себе мозги. Просто я хочу сделать карту, например. Соединенные Штаты, и каждое государство - это другая картина или область, которую можно засунуть и щелкнуть. Я пытался играть с png и прозрачными пленками, но я в тупике. Более амбициозно я хотел бы перетаскивать ярлыки с государственными капиталами над каждым состоянием и отбрасывать их там, тогда есть процесс, когда если метка/капитал соответствует правилу, то это еще не так.Сделать карту кнопок?

Я пробовал GIS (?) Я хочу сделать это C#, но я не могу понять, как это сделать. Может ли кто-нибудь помочь? Это слишком сложно в C#? Должен ли я использовать другой подход? Пожалуйста, какой подход?

ответ

0

Хорошая новость: программная часть не так сложна и даже с хорошими старыми Winforms вы можете выполнять основные проверки в нескольких строках. Однако области с кликами не могут быть кнопками в Winforms.

Вот два решения:

Решение 1: Вы можете определить список областей, называемых регионами и испытания, если один получил щелчок.

Это старт: Я определяю очень простой Rectangle Region и не очень простой Polygon Region и проверяю каждый клик, если был ударил. Если он попал я вывожу свои данные в текст заголовка формы в:

//.. 
using System.Drawing.Drawing2D; 
//.. 
public Form1() 
{ 
    InitializeComponent(); 
    // most real states don't look like rectangles 
    Region r = new Region(new Rectangle(0, 0, 99, 99)); 
    regions.Add(r); 
    List<int> coords = new List<int>() {23,137, 76,151, 61,203, 
         117,283, 115,289, 124,303, 112,329, 76,325, 34,279, 11,162}; 
    List<Point> points = new List<Point>(); 
    for (int i = 0; i < coords.Count ; i += 2) 
         points.Add(new Point(coords[i], coords[i+1])); 
    byte[] fillmodes = new byte[points.Count]; 
    for (int i = 0 ; i < fillmodes.Length; i++) fillmodes[i] = 1; 
    GraphicsPath GP = new GraphicsPath(points.ToArray(), fillmodes); 
    regions.Add(r); 

} 

List<Region> regions = new List<Region>(); 


private void pictureBox1_MouseClick(object sender, MouseEventArgs e) 
{ 
    using (Graphics G = pictureBox1.CreateGraphics()) 
    foreach(Region r in regions) 
    { 
     Region ri = r.Clone(); 
     ri.Intersect(new Rectangle(e.X, e.Y, 1, 1)); 
     if (!ri.IsEmpty(G)) // hurray, we got a hit 
      { this.Text = r.GetBounds(G).ToString(); break; } 
    } 

} 

регионы в тестовой программе не видны. Для тестирования вы можете добавить что-то вроде этого:

private void button1_Click(object sender, EventArgs e) 
{ // paint a non-persistent filling 
    using (Graphics G = pictureBox1.CreateGraphics()) 
     foreach (Region r in regions) 
     { G.FillRegion(Brushes.Red, r); } 
} 

Но теперь плохие новости: Вы можете определить регионы быть сложные многоугольники, которые выглядят как реальные состояния, однако, что это много работы! Есть готовые карты там, где есть веб-страницы для совершения кликов на сайтах. Лучше всего использовать один из них для создания всех этих полигонов, а затем преобразовать вывод html в список точек, которые вы можете прочитать в своей программе. Вы даже можете получить повезло и найти готовые карты изображений для США, но я не смотрел ..

Update: Там являются много карт изображений из США там. Один даже на wikipedia. Преобразование этих координат в соответствии с вашей картой будет задачей, но намного проще, чем создавать их с нуля, imo. Я изменил код, чтобы включить один список шнуров из источника википедии. Угадайте состояние!

Я включил программу, которая позволяет вам щелкнуть по состоянию и отобразить имя в 78 строках кода, за исключением текстового файла с 50 состояниями.

Решение 2:

Вместо списка полигонов можно приготовить цветную карту и использовать цвета в качестве ключей в Dictionary<Color, string> или Dictionary<Color, StateInfo>. Вы должны убедиться, что каждое состояние имеет один уникальный цвет и что изображение не сжато как jpeg, что приведет к появлению артефактов и испортит отображение ключей.

Далее вы сопоставляете каждый цвет с соответствующей информацией; это настоящая работа, потому что вы должны знать эти состояния, чтобы создать словарь ;-)

Наконец, вы можете посмотреть цвет нажатой в Словаре вы создали:

Color c = ((Bitmap) pictureBox1.Image).GetPixel(e.X, e.Y) 
string StateName = stateDictionary[c]; 

Если вы используете класс или структурировать как значение в словаре, вы можете включить капитал и т. д.

Вы можете масштабировать, но должно шкала местоположение щелчка соответственно; вы можете даже отобразить географическое изображение, если вы найдите ключевой цвет не в PictureBox, а в растровом изображении невидимого цвета. В целом даже более простое решение imo .. ваш выбор!

Как только вы получили это, вы можете играть с помощью перетаскивания &. Здесь вы хотите протестировать DragDrop или, возможно, на Mouseup, чтобы узнать, где вы уронили ярлык.

Это хороший проект и стоит создать несколько классов, чтобы сделать вещи проще и более расширяемыми ..!

Для настоящих кнопок вам может повезти с WPF.

+0

Я потратил несколько дней, пытаясь найти понятное решение. Я собираюсь попробовать то, что вы предлагаете медленно шаг за шагом. Мой g_d добавляет возможности asp.net для VS Express примерно в 700 мб. Я собирался попробовать asp, потому что большинство документов поддержки для карт изображений для asp. позвольте мне попытаться заставить ваше предложение кода работать ... спасибо. – user1325143

+0

Я получаю сообщение об ошибке: Ошибка Название «регионы» не существует в текущем контексте \t Я не могу найти метод «добавить» пробные кепки или вариации в «регионах» Я использую VS Express 2010 – user1325143

+0

I посмотрите, что вы пытаетесь сделать, и я попытаюсь заставить его работать. C# сложно, надеюсь, что это сила соответствует его кривой обучения ... – user1325143

Смежные вопросы