Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
buscandoaverroes committed Apr 22, 2024
1 parent 1773946 commit 5251bda
Showing 1 changed file with 136 additions and 2 deletions.
138 changes: 136 additions & 2 deletions transform/convert_quadkey_and_Vertical_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,90 @@ func ConvertExtendedSpatialIDsToQuadkeysAndVerticalIDs(extendedSpatialIDs []stri
return extendedSpatialIDToQuadkeyAndVerticalID, nil
}

func ConvertExtendedSpatialIDsToQuadkeysAndVerticalIDsV2(extendedSpatialIDs []string, outputHZoom int64, outputVZoom int64, outputMaxHeight int64, outputMinHeight int64) ([]*object.FromExtendedSpatialIDToQuadkeyAndVerticalID, error) {
extendedSpatialIDToQuadkeyAndVerticalID := []*object.FromExtendedSpatialIDToQuadkeyAndVerticalID{}

// validate zoom levels
if !quadkeyCheckZoom(outputHZoom, outputVZoom) {
return []*object.FromExtendedSpatialIDToQuadkeyAndVerticalID{}, errors.NewSpatialIdError(errors.InputValueErrorCode, "")
}
// outputのZoomレベルが指定されている前提のため、QuadkeyとAltitudeKeyのみを比較
deduplication := map[[2]int64]interface{}{}

for _, idString := range extendedSpatialIDs {
vIndexes := []int64{}
quadkeys := []int64{}

currentID, error := object.NewExtendedSpatialID(idString)
if error != nil {
return nil, error
}

// hZoom := indexesInt[0]
// xIndex := indexesInt[1]
// yIndex := indexesInt[2]
// vZoom := indexesInt[3]
// vIndex := indexesInt[4]

// check zoom of currentID
if !extendedSpatialIDCheckZoom(currentID.HZoom(), currentID.VZoom()) {
return []*object.FromExtendedSpatialIDToQuadkeyAndVerticalID{}, errors.NewSpatialIdError(errors.InputValueErrorCode, "")
}
// A. convert horizontal IDs to quadkeys to fit output Horizontal Zoom Level
horizontalIDs := integrate.HorizontalZoom(currentID.HZoom(), currentID.X(), currentID.Y(), outputHZoom)

for _, horizontalID := range horizontalIDs {
quadkey := convertHorizontalIDToQuadkey(horizontalID)
quadkeys = append(quadkeys, quadkey)
}

// B. convert vertical IDs to fit Output Vertical Zoom Level
// Here there are three possible cases and the expected output of each
// 1) outputMaxHeight == outputMinHeight: use input verticalIds
// 2) outputMaxHeight > outputMinHeight: use convertBitIndex to find outputBitIndex
// 3) outputMaxHeight < outputMinHeight: should not be possible. Return an error.
if outputMaxHeight == outputMinHeight {
// 精度変換のみ実行する。重複しているIDを削除する
verticalIDs := deleteDuplicationList(integrate.VerticalZoom(currentID.VZoom(), currentID.Z(), outputVZoom))
for _, verticalID := range verticalIDs {
// 「精度/高さのインデックス」 から高さのインデックスのみを抽出する。
vIndex, _ := strconv.ParseInt(strings.Split(verticalID, "/")[1], 10, 64)
vIndexes = append(vIndexes, vIndex)
}

} else if outputMaxHeight > outputMinHeight {
vIndexes, error = convertVerticalIndex(currentID.VZoom(), currentID.Z(), outputVZoom, outputMaxHeight, outputMinHeight)
if error != nil {
return nil, error
}
} else {
return extendedSpatialIDToQuadkeyAndVerticalID,
errors.NewSpatialIdError(errors.InputValueErrorCode, "")
}
// 水平方向と垂直方向の組み合わせを作成する
idList := [][2]int64{}
for _, quadkey := range quadkeys {
for _, vIndex := range vIndexes {
newID := [2]int64{quadkey, vIndex}
if _, ok := deduplication[newID]; ok {
continue
} else {
deduplication[newID] = new(interface{})
}
idList = append(idList, [2]int64{quadkey, vIndex})
}
}
if len(idList) == 0 {
continue
}
newQuadkeyAndVerticalID := object.NewFromExtendedSpatialIDToQuadkeyAndVerticalID(outputHZoom, idList, outputVZoom, float64(outputMaxHeight), float64(outputMinHeight))
extendedSpatialIDToQuadkeyAndVerticalID = append(extendedSpatialIDToQuadkeyAndVerticalID, newQuadkeyAndVerticalID)
}

// 構造体のスライスを返却する。
return extendedSpatialIDToQuadkeyAndVerticalID, nil
}

// ConvertSpatialIDsToQuadkeysAndVerticalIDs 空間IDを内部形式IDに変換する。
//
// 最高高度、最低高度の両方が同じ値の場合、変換後の高さ方向のIDを空間IDインデックス形式とする。
Expand All @@ -354,7 +438,7 @@ func ConvertExtendedSpatialIDsToQuadkeysAndVerticalIDs(extendedSpatialIDs []stri
//
// spatialIDs : 変換対象の空間IDのスライス
//
// outputHZoom : 入力値が変換後のQuadkeyの精度となる。quadkeyの精度の閾値である 1 ~ 31 の整数値を指定可能。
// 1HZoom : 入力値が変換後のQuadkeyの精度となる。quadkeyの精度の閾値である 1 ~ 31 の整数値を指定可能。
//
// outputVZoom : 入力値が変換後の高さの方向IDの精度となる。0 ~ 35 の整数値を指定可能。
//
Expand Down Expand Up @@ -576,6 +660,47 @@ func convertVerticallIDToBit(vZoom int64, vIndex int64, outputZoom int64, maxHei

}

func convertVerticalIndex(inputZoom int64, inputIndex int64, outputZoom int64, outputMaxHeight int64, outputMinHeight int64) ([]int64, error) {

// find height of voxel created by inputIndex
spatialIDMaxHeight := float64(inputIndex+1) * alt25 / float64(math.Pow(2, float64(inputZoom)))
spatialIDMinHeight := float64(inputIndex) * alt25 / float64(math.Pow(2, float64(inputZoom)))

// check if height of SpatialID in input exists in output (at least min must exist)
if spatialIDMinHeight > float64(outputMaxHeight) {
return nil, errors.NewSpatialIdError(errors.InputValueErrorCode, "拡張空間ID形式の高さのインデックスの最低高度はoutputMaxHeightより高いです。/ The Extended SpatialID's vertical index minimum height is greater than outputMaxHeight.")
}

// Calculate the voxel Heights
inputVoxelHeight := calculateVoxelHeight(inputZoom, alt25, 0)
outputVoxelHeight := calculateVoxelHeight(outputZoom, float64(outputMaxHeight), float64(outputMinHeight))

// bitの取得
maxBitIndex := calcBitIndex(spatialIDMaxHeight, outputZoom, float64(outputMaxHeight), float64(outputMinHeight))
minBitIndex := calcBitIndex(spatialIDMinHeight, outputZoom, float64(outputMaxHeight), float64(outputMinHeight))

outputIndexes := []int64{
minBitIndex,
}

// remainder defines whether or not to return maxBitIndex. If remainder is non-zero, the input inputIndex occupies vertical space associated with maxBitIndex. If remainder is zero, [maxBitIndex-1] covers the input inputIndex vertical space perfectly, so maxBitIndex is not needed.
var remainder = math.Mod(inputVoxelHeight, outputVoxelHeight)

// upperIndexLimit is the last bitIndex to be returned. If remainder == 0, reduce upperIndexLimit by 1 to avoid returning superflous upward data.
var upperIndexLimit = maxBitIndex
if remainder == 0 {
upperIndexLimit = maxBitIndex - 1
}

// インデックスの隙間を補完し、IDとして返却用変数に格納する。
for i := minBitIndex + 1; i <= upperIndexLimit; i++ {
outputIndexes = append(outputIndexes, i)
}

return outputIndexes, nil

}

// 高さのbit形式のインデックスを計算する。
//
// 引数 :
Expand All @@ -596,7 +721,7 @@ func calcBitIndex(altitude float64, outputZoom int64, maxHeight float64, minHeig
var i int64
// 出力の精度の回数ループする。
for i = 0; i < outputZoom; i++ {
bit := bitIndex << 1
bit := bitIndex << 1 // bit=0, same type as bitIndex
// 境界の高さを計算する
borderHeight := (maxHeight-minHeight)/2 + minHeight
if altitude >= borderHeight {
Expand All @@ -613,6 +738,15 @@ func calcBitIndex(altitude float64, outputZoom int64, maxHeight float64, minHeig
return bitIndex
}

// VoxelHeight = [spatialIDMaxHeight] - [spatialIDMinHeight], or
//
// = [float64(vIndex+1) * alt25 / float64(math.Pow(2, float64(vZoom))) ] -
// float64(vIndex) * alt25 / float64(math.Pow(2, float64(vZoom)))
// = (globalMaxHeight - globalMinHeight) / float64(math.Pow(2, float64(vZoom)))
func calculateVoxelHeight(vZoom int64, globalMaxHeight float64, globalMinHeight float64) float64 {
return (globalMaxHeight - globalMinHeight) / float64(math.Pow(2, float64(vZoom)))
}

// bit形式のIDを拡張空間ID形式に変換する。
//
// 引数 :
Expand Down

0 comments on commit 5251bda

Please sign in to comment.