2014-09-06 11 views
-1

어떻게해야합니까? 특정 코드를 묻지는 않지만 몇 주 동안 뇌를 긁어 모으기 때문에 어떤 방향이 필요합니다. 간단히 예를 들어지도를 만들고 싶습니다. 미국과 각 주마다 다른 그림이나 영역을 마우스로 클릭하고 클릭 할 수 있습니다. 나는 PNG와 투명 필름으로 노는 시도를했지만 막 다른 골목에있다. 더 야심적으로 각 주에 대한 국가 자본으로 라벨을 드래그하여 그곳에 떨어 뜨린 다음 라벨/자본이 국가와 일치하면 다른 경우를 처리하는 프로세스가 필요합니다.Buttons의지도를 만드시겠습니까?

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 출력을 프로그램에서 읽을 수있는 점 목록으로 변환하는 것입니다. 당신은 행운과 미국에 대한 준비가 이미지 맵을 찾을 수 있습니다,하지만 난 못 봤어 수 있습니다 ..

업데이트을 : 밖에 미국의 많은 이미지 맵이 있습니다. 하나는 wikipedia에 있습니다. 이러한 좌표를지도에 맞게 변환하는 것은 작업이지만 처음부터 새로 만드는 것보다 훨씬 쉽습니다. 위키 피 디아 출처의 한 좌표 명단을 포함하도록 코드를 변경했습니다. 국가 추측!

저는 상태를 클릭하고 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에는 보이지 않지만 보이지 않는 색상 코드 비트 맵으로 검색하면 지리적 이미지를 표시 할 수도 있습니다. 전체적으로 훨씬 간단한 솔루션입니다. 당신의 선택!

작업을 완료하면 & 드래그로 재생할 수 있습니다. 여기서 DragDrop 또는 Mouseup에서 테스트하여 Label을 삭제 한 위치를 확인하고자 할 것입니다.

이것은 멋진 프로젝트이며 일을 더 쉽고 확장 가능하게 만들기위한 몇 가지 수업을 만들 가치가 있습니다 ..!

실제 버튼의 경우 WPF로 운이 좋게 느껴질 수 있습니다.

+0

이해할 수있는 해결책을 찾기 위해 며칠을 보냈습니다. 나는 당신이 천천히 단계적으로 제안하고있는 것을 시도 할 것입니다. VS Express에 asp.net 기능을 추가하는 gd는 약 700MB 다운로드입니다. 이미지 맵에 대한 대부분의 지원 문서는 ASP 용이므로 ASP를 사용하려고했습니다. 당신의 코드 제안을 일하도록 노력합시다 ... 고마워요. – user1325143

+0

오류가 발생했습니다 : 오류 이름 'regions'이 (가) 현재 컨텍스트에 존재하지 않습니다. \t 대문자 또는 변이를 시도하는 "추가"방법을 "지역"에서 찾을 수 없습니다. VS Express 2010을 사용하고 있습니다. – user1325143

+0

I 너가하고있는 것을 보아라. 나는 그것을 일하게하려고 노력할 것이다. C#은 어렵습니다. 힘이 학습 곡선과 일치하기를 바랍니다. – user1325143