KMLのポリゴンはシェープファイルと同じ向きで

たまたま茜丸さんのGE Maniacsを拝見したところ

http://virtual.haru.gs/ge/2010/05/23/mandara%E3%81%A7shape%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92kml%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B-%E5%85%B6%E3%81%AE%E5%BC%90/

MANDARAで高さのあるポリゴンを出力すると色が落ちてしまうらしい。

あまり気にしてなかったけど、日本緯度経度.mpfで適当に都道府県データを出力したところ、確かに暗くなっているようです。でもよく見ると明るい箇所もあります。

やはりポリゴンの座標を並べる順番の問題のようです。ということは、順序を揃えればOKです。

昔シェープファイルのポリゴン座標列を揃える関数を作ったので、それをKML出力の箇所にかませればいいですね。
関数はこれ。

Public Function Get_Polygon_Direction(ByVal Point_Num As Long, pxy() As SingleXY) As Long
'ポリゴンのポイントの並び順を返す
'1:時計回り -1反時計回り
Dim i As Long
Dim minp As Long, Miny_p As SingleXY
Dim Next_p As Long, Before_P As Long
Dim Next_VEC As SingleXY, Before_VEC As SingleXY
Dim Next_D As Single, Before_D As Single
Dim Next_Sin As Single, Next_Cos As Single
Dim Before_Sin As Single, Before_Cos As Single
Dim Next_Angle As Single, Before_Angle As Single

'yが最小の地点を求める
minp = 0
Miny_p = pxy(0)
For i = 1 To Point_Num - 1
If Miny_p.Y > pxy(i).Y Then
Miny_p = pxy(i)
minp = i
End If
Next

'次の地点
Next_p = minp
Do
Next_p = Next_p + 1
If Next_p = Point_Num Then
Next_p = 0
End If
Loop While Check_Two_Point_Same_Single(pxy(Next_p), pxy(minp)) = True

'前の地点
Before_P = minp
Do
Before_P = Before_P - 1
If Before_P = -1 Then
Before_P = Point_Num - 1
End If
Loop While Check_Two_Point_Same_Single(pxy(Before_P), pxy(minp)) = True

'前後の地点との角度を計算して回転方向を求める
With Next_VEC
.X = pxy(Next_p).X - pxy(minp).X
.Y = pxy(Next_p).Y - pxy(minp).Y
Next_D = Sqr(.X ^ 2 + .Y ^ 2)
Next_Sin = .Y / Next_D
Next_Cos = .X / Next_D
Next_Angle = Angle(Next_Sin, Next_Cos)
End With
With Before_VEC
.X = pxy(Before_P).X - pxy(minp).X
.Y = pxy(Before_P).Y - pxy(minp).Y
Before_D = Sqr(.X ^ 2 + .Y ^ 2)
Before_Sin = .Y / Next_D
Before_Cos = .X / Next_D
Before_Angle = Angle(Before_Sin, Before_Cos)
End With
If Before_Angle > Next_Angle Then
Get_Polygon_Direction = 1
Else
Get_Polygon_Direction = -1
End If
End Function

Function Angle(ByVal si, ByVal co)
'サインコサインから角度を返す
If co = 0 Then
Angle = 90
Else
Angle = atn(Abs(si / co)) * 180 / PI
End If
If si >= 0 And co >= 0 Then
ElseIf si >= 0 And co < 0 Then
Angle = 180 - Angle
ElseIf si < 0 And co >= 0 Then
Angle = 360 - Angle
ElseIf si < 0 And co < 0 Then
Angle = 180 + Angle
End If
End Function

しかし、シェープファイルの場合は座標が時計回りか、反時計回りかでポリゴンの外周か、中抜けかを判断する必要があったのですが、KMLの場合はouterBoundaryIsとinnerBoundaryIsタグで外周か中抜けか区別できます。
結局、outerBoundaryIsタグだけでも、座標の向きで中抜きできるということになりますね。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント