폴리곤
외주의 좌표열과, 임의의 수의 구멍(holes)을 가지는 면입니다. 칠과 선의 스타일을 곁들여 지도 뷰에 놓기만 하면, 영역의 표시나 마스크 표현을 할 수 있습니다. 구멍의 취급은 지도 SDK마다 버릇이 있지만, MapConductor는 어느 프로바이더에서도 같은 겉모습이 되도록 맞춰 놓았습니다.
01 · 폴리곤의 상태
PolygonState가 하나의 면을 나타냅니다. 외주・구멍・칠・선・탭 핸들러를 가지며, 프로퍼티를 바꿔 쓰면 형태는 그 자리에서 갱신됩니다. 정점 마커를 드래그해 형태를 편집하는 UI도, 좌표열을 교체하기만 하면 만들 수 있습니다.
val polygonState =
PolygonState(
points = outerRing,
holes = listOf(holeA, holeB),
strokeColor = Color.Red,
strokeWidth = 3.dp,
fillColor = Color(0x4D0064E6),
onClick = { event -> viewModel.onPolygonClick(event) },
)
Polygon(polygonState)
// 정점도 구멍도 다시 쓰기만 하면 갱신된다
polygonState.holes = nextHoleslet polygonState = PolygonState(
points: outerRing,
strokeColor: .red,
strokeWidth: 3.0,
fillColor: UIColor(red: 0, green: 0.39, blue: 0.9, alpha: 0.3),
holes: [holeA, holeB],
onClick: { event in viewModel.onPolygonClicked(event) }
)
content.polygons = [Polygon(state: polygonState)]const polygonState = createPolygonState({
id: 'demo-polygon',
points: vertices,
holes,
strokeColor: '#e74c3c',
strokeWidth,
fillColor: `rgba(0, 100, 230, ${fillOpacity})`,
onClick: () => showToast('Polygon clicked'),
});
<Polygon state={polygonState} />02 · 구멍(holes)과 겹침의 결합
구멍은 외주에서 빼내는 영역입니다. 마스크 표현에서는 「보여 주고 싶은 곳」을 구멍으로 여러 개 두는 일이 자주 있는데, 그때 구멍끼리 겹치는 것은 자연스럽게 일어납니다.
많은 지도 SDK는 겹치는 구멍을 그대로 넘기면 겹친 부분에 윤곽선을 그려 버려, 구멍과 구멍의 경계가 보이고 맙니다. MapConductor는 넘겨받은 구멍을 결합한 뒤에 그리기 때문에, 겹침은 하나의 구멍으로 다뤄지고 여분의 선은 나오지 않습니다.


// 겹치는 구멍은 그대로 넘겨도 된다. 내부에서 하나로 결합된다
PolygonState(
points = outerRing,
holes =
listOf(
triangleA, // ← 여기가 겹친다
triangleB,
),
fillColor = Color(0xCC787880),
)// 겹치는 구멍은 그대로 넘겨도 된다. 내부에서 하나로 결합된다
let state = PolygonState(
points: outerRing,
fillColor: UIColor(white: 0.47, alpha: 0.8),
holes: [triangleA, triangleB]
)// 겹치는 구멍은 그대로 넘겨도 된다. 내부에서 하나로 결합된다
const state = createPolygonState({
id: 'world-hole',
points: OUTER_POINTS,
holes, // 서로 겹치는 두 개의 삼각형
fillColor: 'rgba(120, 120, 128, 0.8)',
strokeColor: '#ef4444',
strokeWidth: 2,
});03 · 어느 프로바이더에서도 같게 보인다
구멍의 겹침 외에도, 면의 렌더링에는 엔진마다 차이가 나기 쉬운 곳이 있습니다. MapConductor는 그것들을 내부에서 흡수해, 같은 PolygonState에서 같은 그림이 되도록 하고 있습니다.
겹치는 구멍을 결합한다
구멍끼리의 겹침은, 상태를 만드는 단계에서 하나의 영역으로 결합됩니다. 윤곽선이 겹침 부분에 나타나는 일도, 칠이 이중이 되는 일도 없습니다.
곡선을 그릴 수 없는 엔진에도 같은 형태를
대권 코스를 직접 그릴 수 없는 엔진에는, 변을 잘게 분할한 좌표열로 변환한 뒤 넘깁니다. 광역의 영역에서도 형태가 일치합니다.
날짜변경선을 넘는 면
경도 180도를 넘는 면은 경계에서 분할해 넘깁니다. 지구를 반대로 횡단하는 칠이 되는 엔진에서도 올바른 쪽이 칠해집니다.
탭 판정도 공통
탭 판정은 공통 로직으로 하며, 구멍의 안쪽은 탭에 반응하지 않습니다. 엔진이 구멍을 고려하는지 여부와 관계없이, 보이는 그대로의 판정이 됩니다.
04 · 탭
onClick은 면의 상태와, 탭된 좌표를 받습니다. 칠이나 extra에서 데이터를 꺼내 상세를 표시하는 것이 정석적인 사용법입니다.
탭된 면의 상태. 칠 색이나 extra에서 데이터를 꺼낼 수 있습니다.
탭된 지리 좌표.
구멍의 안쪽을 탭해도, 그 면의 이벤트는 발화하지 않습니다. 보이는 칠 부분만이 대상입니다.
fun onPolygonClicked(event: PolygonEvent) {
markerState = MarkerState(
position = event.clicked,
icon = DefaultMarkerIcon(fillColor = event.state.fillColor),
)
}func onPolygonClicked(_ event: PolygonEvent) {
let color = event.state.fillColor.withAlphaComponent(1.0)
markerState = MarkerState(
position: GeoPoint.from(position: event.clicked),
id: "clicked",
icon: DefaultMarkerIcon(fillColor: color)
)
}onClick: event => {
setMarker(createMarkerState({
id: 'clicked',
position: event.clicked,
icon: new ColorDefaultIcon({ fillColor: event.state.fillColor }),
}));
},면이 겹쳐 있는 경우에는 위(zIndex가 큰 쪽)가 우선됩니다. 넓은 영역을 여러 면 놓아도, 표시 범위 밖의 면은 판정에서 제외됩니다.