静止画地図表示範囲の緯度経度を計算する（BingMapsScaleコンポーネントの改善）

※当初のタイトルは「BingMapsScaleコンポーネントの改善」でしたが、本稿の内容はコンポーネントに関しては特定の地図サービスに依存しない計算なので「静止画地図表示範囲の緯度経度を計算する」に変更しました。後半の確認ではBingMapsを使います。
#はじめに
次回はマルチポイントのタップに対応したコンポーネントの紹介、と書いていましたが、
以前の記事「[PowerAppsでBingMapsを活用する時のお決まり計算をコンポーネントに](https://qiita.com/kenjik/items/d7ef4c5ba05cb8997ae7)」で作ったコンポーネント（ここではBingMapsScaleコンポーネントと呼びます）を使っていて、気になる点が出てきました。

1. コンポーネント内のコントロールと同じコントロール名をアプリ内で使えない。
2. コンポーネントを使う時、同時に地図の表示範囲を計算することが多い（データを絞り込むため）。
3. コンポーネントのアウトプットを使うタイミングによっては、初期値が渡されてしまう。

次の記事で使う前に、このうちの１と２を改善しておこうと思います（３を無くす方法は思いついていない）。
前回からの差分しか書いていないので、最初から作るには以下の記事を参照してください。

* [PowerAppsでBingMapsを活用する時のお決まり計算をコンポーネントに](https://qiita.com/kenjik/items/d7ef4c5ba05cb8997ae7)

#まずは出来上がりから
前回の記事からの変更点です。

* コンポーネント名を「cmpBingMapsScale」に変更しました。
* 先述の1.の課題であるコントロール名の衝突を防ぐために、すべてのコントロールの後ろに「_cmpBMS」を付けました。
* 地図の表示範囲を出すために、カスタムプロパティの入力項目として Longitude、MapXPixels、MapYPixels（青い部分）、出力項目として
MapLatitudeFrom、MapLatitudeTo、MapLongitudeFrom、MapLongitudeTo（赤い部分）を追加しました。
![kansei.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278581/36b48dc7-9648-06ed-5746-60a5dd4bcbb7.jpeg)
![tizuhanni.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278581/7dfd61a1-932a-6779-04b0-6f8c7c019d93.jpeg)


##入力項目の設定
以下の３つのカスタムプロパティを設定します。

| 表示名 | 名前 | プロパティの型 | データ型 | コメント |
|:-:|:-:|:-:|:-:|:-:|
| Longitude | Longitude | 入力 | 数値 | 地図中央の経度。初期値は任意ですが仮に135とします |
| MapXPixels | MapXPixels | 入力 | 数値 | 地図の横幅をピクセルで設定します。初期値は仮に400とします |
| MapYPixels | MapYPixels | 入力 | 数値 | 地図の高さをピクセルで設定します。初期値は仮に300とします |

##地図範囲の計算
地図範囲を示す緯度経度を計算するために、以下４つのラベルコントロールを追加し、それぞれのTextプロパティに式を設定します。
計算にあたっては、中央(0,0)に１ピクセル使われるため、地図のピクセル数が偶数の場合、マイナス部分のピクセル数を１減らすことにします。
例えば横幅400ピクセルだと、（-199 ～ 200）が範囲となります。

| ラベルコントロールの名前 | プロパティ名 | 設定値 |　コメント |
|:-:|:-:|:---------------------------:|:------------------------:|
| MapLatitudeFrom_cmpBMS | Text | cmpBingMapsScale.Latitude-LatitudePer1000Pixels_cmpBMS*(RoundUp(MapYPixels_cmpBMS/2,0)-1)/1000 | 地図の表示範囲の最小の緯度。地図の中心から、高さの半分に相当する度数を引きます。 |
| MapLatitudeTo_cmpBMS | Text | cmpBingMapsScale.Latitude+LatitudePer1000Pixels_cmpBMS*RoundDown(MapYPixels_cmpBMS/2,0)/1000 | 地図の表示範囲の最大の緯度。地図の中心から、高さの半分に相当する度数を足します。 |
| MapLongitudeFrom_cmpBMS | Text | cmpBingMapsScale.Longitude-LongitudePer1000Pixels_cmpBMS*(RoundUp(MapXPixels_cmpBMS/2,0)-1)/1000 | 地図の表示範囲の最小の経度。地図の中心から、横幅の半分に相当する度数を引きます。 |
| MapLongitudeTo_cmpBMS | Text | cmpBingMapsScale.Longitude+LongitudePer1000Pixels_cmpBMS*RoundDown(MapXPixels_cmpBMS/2,0)/1000 | 地図の表示範囲の最大の経度。地図の中心から、横幅の半分に相当する度数を足します。 |

##出力項目の設定
以下の４つのカスタムプロパティを設定します。

| 表示名 | 名前 | プロパティの型 | データ型 | コメント |
|:-:|:-:|:-:|:-:|:-:|
| MapLatitudeFrom | MapLatitudeFrom | 出力 | 数値 | 地図の表示範囲の最小の緯度 |
| MapLatitudeTo | MapLatitudeTo | 出力 | 数値 | 地図の表示範囲の最大の緯度 |
| MapLongitudeFrom | MapLongitudeFrom | 出力 | 数値 | 地図の表示範囲の最小の経度 |
| MapLongitudeTo | MapLongitudeTo | 出力 | 数値 | 地図の表示範囲の最大の経度 |

それぞれのカスタムプロパティに、先程の計算結果を割り当てます。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278581/cb6e2eaf-403a-7613-6922-59ca186bb8e3.png)

#確認してみよう
確認のために、イメージコントロールを２つ準備し、１つには地図の中心となる緯度経度、もうひとつには地図の緯度経度範囲を指定して、内容を較べてみることにしましょう。表示位置は前記事と同じ東京駅近くの{35.68111701,139.76362492}にします。
それぞれのイメージコントロールのImageプロパティは、以下のような記述になると思います。

```php:Image1.Image
"https://dev.virtualearth.net/REST/v1/Imagery/Map/Road/35.68111701,139.76362492/17?mapSize=600,350&Key=YourAPIKey"
```
```php:Image2.Image
"https://dev.virtualearth.net/REST/v1/Imagery/Map/Road?zoomLevel=17&mapArea=" & cmpBingMapsScale_1.MapLatitudeFrom & "," & cmpBingMapsScale_1.MapLongitudeFrom & "," & cmpBingMapsScale_1.MapLatitudeTo & "," & cmpBingMapsScale_1.MapLongitudeTo & "&mapSize=600,350&Key=YourAPIKey"
```

![maptest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278581/f6d4a3c1-46cf-4e39-75df-f35eb41d5028.png)
どうやら同じ範囲になっているようです。
（この部分、表示範囲を指定しているのだからZoomLevelが必要ないと思うのですが、外すと表示範囲が一回り大きくなります。４隅の緯度経度を確認する限りzoomLevelを付けた時の表示のほうが正しいので、付けたままにしています）

この範囲を使うことで、元のデータから地図に表示される範囲内にあるレコードを抽出することが出来るようになりました。

#最後に
今回はちょっと寄り道して、コンポーネント改善の記事でした。
次回はいよいよタップに対応していきます。