Svelteでmapray JSの環境を作る

# Maprayとは
ソニーグループ株式会社が開発しているデジタルツインの開発者向けプラットフォーム。

以下の2つのコンテンツによって成り立っている
- Mapray Cloud
- mapray JS

現状では、Mapray Cloudの利用は必須。

出典: [mapray](https://mapray.com/#:~:text=Mapray(%E3%83%9E%E3%83%83%E3%83%97%E3%83%AC%E3%82%A4)%E3%81%AF%E3%80%81,%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)

今回はMaprayを扱うためのJavaScriptライブラリ「mapray JS」をSvelteで扱ってみる。（競合としては[CesiumJS](https://cesium.com/platform/cesiumjs/)）

[リポジトリ](https://github.com/TakamuneSuda/sample-mapray)

# TL;DR
とりあえずはMapray UIライブラリ「StandardUIViewer」を使うと良さそう

[公式ドキュメント](https://mapray.com/documents/developer-guide/ui-library/)

# 準備

1. Mapray Cloudのトークン発行
あらかじめ[Mapray Cloud](https://cloud.mapray.com/)でトークン（API Key）を発行する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336887/45ddbc64-0d5e-4680-a39a-22c06992d099.png)

1. Svelteプロジェクト作成
https://svelte.jp/docs/kit/creating-a-project
![スクリーンショット 2025-04-25 7.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336887/3b5ed27e-2aa9-41dc-bb82-820c07fda822.png)
使用環境
Vite: 6.2.5
Svelte: 5.0.0
SvelteKit: 2.16.0

1. Mapray Cloudのトークン適用
Mapray Cloudのトークンを作成したSvelteプロジェクトの環境変数に入れる。
.env
`VITE_MAPRAY_ACCESS_TOKEN={発行したトークン}`

# コード 

+page.svelte
```
<script lang="ts">
  import { onMount } from 'svelte';
  import mapray from "@mapray/mapray-js";
  import maprayui from "@mapray/ui";

  // Reference to the DOM element for the Mapray viewer container
  let mapContainer: HTMLElement;

  // Instance of the Mapray viewer
  let stdViewer: maprayui.StandardUIViewer | null = null;

  // Specify the pre-obtained access token. Reads from environment variable.
  const ACCESS_TOKEN = import.meta.env.VITE_MAPRAY_ACCESS_TOKEN;

  // Run after the component is mounted
  onMount(() => {
    if (!mapContainer) {
      console.error("Map container element not found");
      return;
    }
    if (!ACCESS_TOKEN) {
      console.error("Mapray access token is not defined");
      // Optionally, display an error message to the user here
      return;
    }

    // Initialize Mapray viewer
    stdViewer = new maprayui.StandardUIViewer(mapContainer, ACCESS_TOKEN);

    // Position of Mt. Fuji
    const mtFujiPosition = new mapray.GeoPoint(138.72884, 35.36423, 0);

    // Change camera position
    stdViewer.setCameraPosition({
      longitude: mtFujiPosition.longitude,
      latitude: mtFujiPosition.latitude - 0.05,
      height: mtFujiPosition.altitude + 6000
    });

    // Change look-at position
    stdViewer.setLookAtPosition({
      longitude: mtFujiPosition.longitude,
      latitude: mtFujiPosition.latitude,
      height: mtFujiPosition.altitude + 3000
    });

    // Create and add pin entity
    const pin = new mapray.PinEntity(stdViewer.viewer.scene);
    pin.altitude_mode = mapray.AltitudeMode.RELATIVE;
    pin.addMakiIconPin( "mountain-15", mtFujiPosition );
    stdViewer.addEntity(pin);

    // Return a cleanup function to be called when the component is destroyed
    return () => {
      if (stdViewer) {
        stdViewer.destroy(); // Release viewer resources
        stdViewer = null;
      }
    };
  });

</script>

<div
  bind:this={mapContainer}
  class="w-screen h-screen"
>
</div>
```

現状ではmapray JSはSSR対応していないようなので、SSRを無効にするか動的インポートする必要がある。今回はSSRを無効にした。

+page.ts
```
export const ssr = false;
```

すると無事表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336887/56a9ea0f-fd70-4ed2-83ec-bfd6b6f0bd28.png)

# ついでに
Amplifyにホストしました。
現状地形だけしか見えませんが、結構早いです！！！！！
https://main.d1e9sei1slaknc.amplifyapp.com/