C# GMap.NET 강좌 : 제 8강 - 사용자 정의 다각형
사용자 정의 다각형(Custom Polygon)
기존 GMap.Net
의 다각형 클래스는 구멍이 있는 다각형을 지원하지 않습니다.
그러므로, 다각형(GMapPolygon)
클래스를 재정의하여 구멍이 있는 다각형을 구현할 수 있습니다.
다각형을 재정의한다면 기존 다각형에서 지원되지 않는 기능을 덧붙여 새로운 다각형을 생성할 수 있습니다.
클래스 코드
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsForms;
namespace Project
{
class Map
{
public GMapControl App;
public GMapOverlay PolygonOverlay = new GMapOverlay("polygons");
public Map(GMapControl app)
{
// App Connection
this.App = app;
this.App.MapProvider = GMapProviders.GoogleMap;
this.App.Overlays.Add(PolygonOverlay);
// Default Zoom Level
this.App.Zoom = 16;
this.App.MaxZoom = 25;
this.App.MinZoom = 5;
// Default Position
this.App.Position = new PointLatLng(37.497872, 127.0275142);
// Outer & Inner Position
List<PointLatLng> outer = new List<PointLatLng>
{
new PointLatLng(37.5012147086396, 127.02392578125),
new PointLatLng(37.4951541896508, 127.02321767807),
new PointLatLng(37.4952563373043, 127.03165054321),
new PointLatLng(37.5014189872271, 127.03104972839)
};
List<PointLatLng> inner = new List<PointLatLng>
{
new PointLatLng(37.4993931998586, 127.025470733643),
new PointLatLng(37.4966182926675, 127.025406360626),
new PointLatLng(37.4968055595875, 127.030062675476),
new PointLatLng(37.4998528371071, 127.029933929443)
};
GMapPolygonWithHole gMapPolygonWithHole = new GMapPolygonWithHole(outer, inner, "hole");
gMapPolygonWithHole.Fill = new SolidBrush(Color.FromArgb(50, Color.Black));
gMapPolygonWithHole.Stroke = new Pen(Color.Red, 2);
PolygonOverlay.Polygons.Add(gMapPolygonWithHole);
}
public class GMapPolygonWithHole : GMapPolygon
{
List<PointLatLng> Outer;
List<PointLatLng> Inner;
public GMapPolygonWithHole(List<PointLatLng> outer, List<PointLatLng> inner, string name) : base(outer, name)
{
Outer = outer;
Inner = inner;
}
public override void OnRender(Graphics g)
{
using (GraphicsPath OuterPath = new GraphicsPath())
using (GraphicsPath InnerPath = new GraphicsPath())
{
PointF[] outer = new PointF[Outer.Count];
PointF[] inner = new PointF[Inner.Count];
GPoint point = Overlay.Control.FromLatLngToLocal(Outer[0]);
GPoint offset = new GPoint(point.X - LocalPoints[0].X, point.Y - LocalPoints[0].Y);
for (int i = 0; i < Outer.Count; i++)
{
GPoint pt = Overlay.Control.FromLatLngToLocal(Outer[i]);
outer[i] = new PointF(pt.X - offset.X, pt.Y - offset.Y);
}
for (int i = 0; i < Inner.Count; i++)
{
GPoint pt = Overlay.Control.FromLatLngToLocal(Inner[i]);
inner[i] = new PointF(pt.X - offset.X, pt.Y - offset.Y);
}
OuterPath.AddPolygon(outer);
InnerPath.AddPolygon(inner);
using (Region region = new Region(OuterPath))
{
region.Exclude(InnerPath);
g.FillRegion(Fill, region);
g.DrawPolygon(Stroke, inner);
g.DrawPolygon(Stroke, outer);
}
}
}
}
}
}
세부 코드
GMapPolygonWithHole
public class GMapPolygonWithHole : GMapPolygon
{
...
}
사용자 정의 다각형을 생성하기 위해 GMapPolygon
클래스를 상속받아 GMapPolygonWithHole
로 재정의합니다.
GMapPolygonWithHole
클래스는 구멍이 있는 다각형을 그립니다.
public class GMapPolygonWithHole : GMapPolygon
{
List<PointLatLng> Outer;
List<PointLatLng> Inner;
...
}
GMapPolygonWithHole
클래스에 사용될 외곽(Outer)
, 내곽(Inner)
을 선언합니다.
외곽(Outer)
은 다각형의 외부를 의미합니다.
내곽(Inner)
은 다각형의 구멍을 의미합니다.
public GMapPolygonWithHole(List<PointLatLng> outer, List<PointLatLng> inner, string name) : base(outer, name)
{
Outer = outer;
Inner = inner;
}
GMapPolygonWithHole
는 입력값으로 외곽(outer)
, 내곽(inner)
, 다각형 이름(name)
을 사용합니다.
base
키워드를 통해 부모 클래스의 가르킵니다.
OnRender
public override void OnRender(Graphics g)
{
...
}
OnRender
메서드를 오버라이드(Override)
하여 재정의합니다.
OnRender
메서드는 렌더링될 때 실행되는 메서드입니다.
즉, 렌더링 메서드를 재정의하여 기존에 그려지는 방식과 다른 방식으로 그립니다.
public override void OnRender(Graphics g)
{
using (GraphicsPath OuterPath = new GraphicsPath())
using (GraphicsPath InnerPath = new GraphicsPath())
{
PointF[] outer = new PointF[Outer.Count];
PointF[] inner = new PointF[Inner.Count];
}
}
구멍이 있는 다각형을 그릴 예정이므로 외곽과 내곽의 경로를 입력할 그래픽스 경로(GraphicsPath)
를 생성합니다.
리소스를 자동으로 해제하기 위해 using
키워드를 활용하여 묶어줍니다.
그래픽스 경로(GraphicsPath)
는 PointF[]
형식의 변수를 입력값으로 받으므로, outer
와 inner
를 초기화합니다.
PointF[] outer = new PointF[Outer.Count];
PointF[] inner = new PointF[Inner.Count];
GPoint point = Overlay.Control.FromLatLngToLocal(Outer[0]);
GPoint offset = new GPoint(point.X - LocalPoints[0].X, point.Y - LocalPoints[0].Y);
다각형 그리기의 위치를 보정하기 위해 오프셋(offset)
을 계산합니다.
LocalPoints
필드는 GMapPolygon
클래스의 GPoint
좌표가 저장되어 있습니다.
해당 좌표는 Outer
좌표와 매핑되지만, 동일한 위치에 그려지지 않습니다.
그러므로, Outer
의 첫 번째 좌표와 LocalPoints
의 첫 번째 좌표의 차이를 계산하여 모든 좌표의 오프셋으로 적용합니다.
Overlay
속성의 Control
속성에서 위도/경도를 지역 좌표로 변경할 수 있습니다.
for (int i = 0; i < Outer.Count; i++)
{
GPoint pt = Overlay.Control.FromLatLngToLocal(Outer[i]);
outer[i] = new PointF(pt.X - offset.X, pt.Y - offset.Y);
}
for (int i = 0; i < Inner.Count; i++)
{
GPoint pt = Overlay.Control.FromLatLngToLocal(Inner[i]);
inner[i] = new PointF(pt.X - offset.X, pt.Y - offset.Y);
}
OuterPath.AddPolygon(outer);
InnerPath.AddPolygon(inner);
FromLatLngToLocal
메서드를 활용하여 좌표로 변환하고, 오프셋 만큼 감산을 진행합ㄴ디ㅏ.
외곽과 내곽에 대해 동일하게 처리하고, 각각의 그래픽스 경로(GraphicsPath)
에 추가합니다.
using (Region region = new Region(OuterPath))
{
region.Exclude(InnerPath);
g.FillRegion(Fill, region);
g.DrawPolygon(Stroke, inner);
g.DrawPolygon(Stroke, outer);
}
내부에 구멍이 있는 다각형을 그릴 예정이므로, Region
클래스를 활용합니다.
Exclude
메서드를 통해 다각형에서 특정 다각형을 제외할 수 있습니다.
제외된 클래스를 그래픽스에 그립니다.
내부 색상은 GMapPolygon
클래스의 Fill
속성을 그대로 사용합니다.
DrawPolygon
메서드를 통해 다각형의 외곽 및 내곽 라인을 그립니다.
선의 색상은 GMapPolygon
클래스의 Stroke
속성을 그대로 사용합니다.
Map
// Outer & Inner Position
List<PointLatLng> outer = new List<PointLatLng>
{
new PointLatLng(37.5012147086396, 127.02392578125),
new PointLatLng(37.4951541896508, 127.02321767807),
new PointLatLng(37.4952563373043, 127.03165054321),
new PointLatLng(37.5014189872271, 127.03104972839)
};
List<PointLatLng> inner = new List<PointLatLng>
{
new PointLatLng(37.4993931998586, 127.025470733643),
new PointLatLng(37.4966182926675, 127.025406360626),
new PointLatLng(37.4968055595875, 127.030062675476),
new PointLatLng(37.4998528371071, 127.029933929443)
};
GMapPolygonWithHole gMapPolygonWithHole = new GMapPolygonWithHole(outer, inner, "hole");
gMapPolygonWithHole.Fill = new SolidBrush(Color.FromArgb(50, Color.Black));
gMapPolygonWithHole.Stroke = new Pen(Color.Red, 2);
PolygonOverlay.Polygons.Add(gMapPolygonWithHole);
기존 다각형의 추가 방식과 동일한 방식으로 등록합니다.
단, 내곽을 새로 정의하여 추가합니다.
출력 결과
공유하기


댓글 남기기