0.0.12 • Published 3 months ago

@takamunesuda/svecium v0.0.12

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

svecium

svecium is a minimal Svelte 5 component library that wraps CesiumJS, making it easy to build interactive 3D globes and maps in Svelte apps. Compose Cesium features using simple Svelte components—no boilerplate, no hassle.


How to Build (Setup)

1. Vite Configuration (vite.config.ts)

You must configure your Vite project as follows to use svecium with CesiumJS:

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';

export default defineConfig({
  plugins: [
    sveltekit(),
    viteStaticCopy({
      targets: [
        { src: 'node_modules/cesium/Build/Cesium/Workers/*', dest: 'cesium/Workers' },
        { src: 'node_modules/cesium/Build/Cesium/Assets/*', dest: 'cesium/Assets' },
        { src: 'node_modules/cesium/Build/Cesium/Widgets/*', dest: 'cesium/Widgets' },
        { src: 'node_modules/cesium/Build/Cesium/ThirdParty/*', dest: 'cesium/ThirdParty' }
      ]
    })
  ],
  define: {
    CESIUM_BASE_URL: JSON.stringify('/cesium')
  }
});

2. Import Cesium CSS

You must import Cesium’s widget CSS in your app (typically where you use the Viewer component):

import 'cesium/Build/Cesium/Widgets/widgets.css';

3. Requirements

  • Svelte 5
  • CesiumJS
  • Vite

Components

Viewer

The Viewer component creates a Cesium Viewer instance and allows you to compose map-related child components (such as Terrain, Imagery, Camera, etc.) inside.

Props

NameTypeRequiredDescription
ionTokenstringOptionalCesium Ion access token. Required for Cesium Ion assets (e.g., terrain, 3D Tiles).
childrenslotOptionalMap-related child components. Usually required for meaningful usage.

Note:

  • ionToken is optional in the type definition, but required if you use Cesium Ion assets.
  • children is optional in the type definition, but the Viewer is only useful with child components such as Terrain, Imagery, Camera, etc.

Minimal Example

<Viewer ionToken="your_ion_token">
  <Terrain assetId={1234} />
  <Imagery url={tileUrl} />
  <Camera ...props />
</Viewer>
interface ViewerProps {
  ionToken?: string;
  children?: Snippet<[Viewer]>;
}

Terrain

The Terrain component adds a Cesium terrain provider to the Viewer context using a Cesium Ion asset.

Props

NameTypeRequiredDescription
assetIdnumberOptionalCesium Ion asset ID for the terrain provider

Minimal Example

<Viewer ionToken="your_ion_token">
  <Terrain assetId={1234} />
</Viewer>
interface TerrainProps {
  assetId?: number;
}

Camera

The Camera component sets the initial camera position and orientation for the Cesium Viewer. You can control the view by specifying longitude, latitude, height, heading, pitch, and roll. All props are optional and bindable for reactive camera control.

Props

NameTypeRequiredDescription
longitudenumberOptionalLongitude in degrees
latitudenumberOptionalLatitude in degrees
heightnumberOptionalHeight in meters
headingnumberOptionalHeading in degrees
pitchnumberOptionalPitch in degrees
rollnumberOptionalRoll in degrees

Minimal Example

<Viewer ionToken="your_ion_token">
  <Camera longitude={139.7673} latitude={35.6812} height={1000} heading={0} pitch={-30} roll={0} />
</Viewer>
interface CameraProps {
  longitude?: number;
  latitude?: number;
  height?: number;
  heading?: number;
  pitch?: number;
  roll?: number;
}

Imagery

The Imagery component adds a raster tile imagery layer to the Cesium Viewer using a URL template (e.g., OpenStreetMap, Mapbox, XYZ, etc.).

Props

NameTypeRequiredDescription
urlstringRequiredURL template for raster tiles
minimumLevelnumberOptionalMinimum zoom level (default: 0)
maximumLevelnumberOptionalMaximum zoom level (default: 18)

Minimal Example

<Viewer ionToken="your_ion_token">
  <Imagery url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" minimumLevel={0} maximumLevel={19} />
</Viewer>
interface ImageryProps {
  url: string;
  minimumLevel?: number;
  maximumLevel?: number;
}

GeoJSONPoint

The GeoJSONPoint component renders GeoJSON Point features on the Cesium globe. You can style points with custom images, colors, size, and more.

Props

NameTypeRequiredDescription
dataFeatureCollection | Feature | nullYesGeoJSON Point feature or feature collection.
stylePointStyleOptionalStyle options for points (color, opacity, pointSize, outline, image, etc).
clampToGroundbooleanOptionalClamp points to ground (default: false).
heightOffsetnumberOptionalPixel offset from ground (default: undefined).

Minimal Example

<Viewer ionToken="your_ion_token">
  <GeoJSONPoint
    data={geojsonPointData}
    style={{
      pointImage: imageUrl, // image url
      imageWidth: 32,
      imageHeight: 48,
      rotation: 45,
      anchorX: 0.5,
      anchorY: 1,
      color: '#4169e1',
      opacity: 0.8
    }}
    clampToGround={true}
  />
</Viewer>
interface GeoJSONPointProps {
  data: FeatureCollection<Point> | Feature<Point> | null;
  style?: PointStyle;
  clampToGround?: boolean;
  heightOffset?: number;
}

GeoJSONLine

The GeoJSONLine component renders GeoJSON LineString features as polylines on the Cesium globe. Supports color, width, opacity, outline, and ground clamping.

Props

NameTypeRequiredDescription
dataFeatureCollection | Feature | nullYesGeoJSON LineString feature or feature collection.
styleLineStyleOptionalStyle options for lines (color, opacity, lineWidth, outline, etc).
clampToGroundbooleanOptionalClamp lines to ground (default: false).
heightOffsetnumberOptionalHeight offset for line positions (default: undefined).

Minimal Example

<Viewer ionToken="your_ion_token">
  <GeoJSONLine
    data={geojsonLineData}
    style={{
      color: '#ff0000',
      opacity: 1,
      lineWidth: 12,
      outlineColor: '#ffffff',
      outlineWidth: 1
    }}
    clampToGround={true}
  />
</Viewer>
interface GeoJSONLineProps {
  data: FeatureCollection<LineString> | Feature<LineString> | null;
  style?: LineStyle;
  clampToGround?: boolean;
  heightOffset?: number;
}

GeoJSONPolygon

The GeoJSONPolygon component renders GeoJSON Polygon features as filled polygons on the Cesium globe. You can style fill color, opacity, outline, and more.

Props

NameTypeRequiredDescription
dataFeatureCollection | Feature | nullYesGeoJSON Polygon feature or feature collection.
stylePolygonStyleOptionalStyle options for polygons (fillColor, fillOpacity, outlineColor, outlineWidth, etc).

Minimal Example

<Viewer ionToken="your_ion_token">
  <GeoJSONPolygon
    data={geojsonPolygonData}
    style={{
      fillColor: '#ff0000',
      fillOpacity: 0.5,
      outlineColor: '#000000',
      outlineWidth: 2
    }}
  />
</Viewer>
interface GeoJSONPolygonProps {
  data: FeatureCollection<Polygon> | Feature<Polygon> | null;
  style?: PolygonStyle;
}

Mvt

The Mvt component adds a Mapbox Vector Tile (MVT) layer to the Cesium globe using an MVT imagery provider. You can customize stroke color, fill color, line width, and handle feature selection.

Props

NameTypeRequiredDescription
urlstringYesURL template for the MVT tiles.
layerNamestringYesName of the vector tile layer to display.
strokeStylestringOptionalStroke color for features (default: '#000000').
fillStylestringOptionalFill color for features (default: '#ffffff').
lineWidthnumberOptionalLine width for features (default: 2).
onSelectFeature(feature: any) => voidOptionalCallback when a feature is selected.

Minimal Example

<Viewer ionToken="your_ion_token">
  <Mvt
    url="https://example.com/tiles/{z}/{x}/{y}.pbf"
    layerName="myLayer"
    strokeStyle="#0080ff"
    fillStyle="#00ff80"
    lineWidth={3}
    onSelectFeature={(feature) => console.log(feature)}
  />
</Viewer>
interface MvtProps {
  url: string;
  layerName: string;
  strokeStyle?: string;
  fillStyle?: string;
  lineWidth?: number;
  onSelectFeature?: (feature: any) => void;
}

Full Example: All-in Svelte Globe

<script lang="ts">
  import { Viewer, Imagery, Terrain, Camera, GeoJSONPoint, GeoJSONLine, GeoJSONPolygon, Mvt } from '@TakamuneSuda/svecium';

  const ionToken = 'your_cesium_ion_token';
  const tileUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
  const mvtUrl = 'https://example.com/tiles/{z}/{x}/{y}.pbf';
  const mvtLayer = 'myLayer';

  // GeoJSONデータ例
  const geojsonPointData = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: { type: 'Point', coordinates: [139.7673068, 35.681236] },
        properties: { name: 'Tokyo Station' }
      }
    ]
  };
  const geojsonLineData = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: { type: 'LineString', coordinates: [ [139.76, 35.68], [139.77, 35.69] ] },
        properties: {}
      }
    ]
  };
  const geojsonPolygonData = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: { type: 'Polygon', coordinates: [ [ [139.76, 35.68], [139.77, 35.68], [139.77, 35.69], [139.76, 35.69], [139.76, 35.68] ] ] },
        properties: {}
      }
    ]
  };
  const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/4/4e/Pleiades_large.jpg';

  let latitude = $state(35.681236);
  let longitude = $state(139.7673068);
  let height = $state(10000);
  let heading = $state(0);
  let pitch = $state(-30);
  let roll = $state(0);
</script>

<div class="h-screen">
  <Viewer {ionToken}>
    <Terrain assetId={1234} />
    <Imagery url={tileUrl} minimumLevel={0} maximumLevel={19} />
    <Camera bind:latitude bind:longitude bind:height bind:heading bind:pitch bind:roll />
    <GeoJSONPoint
      data={geojsonPointData}
      style={{
        pointImage: imageUrl,
        imageWidth: 32,
        imageHeight: 48,
        rotation: 0,
        anchorX: 0.5,
        anchorY: 1,
        color: '#4169e1',
        opacity: 0.8
      }}
      clampToGround={true}
    />
    <GeoJSONLine
      data={geojsonLineData}
      style={{
        color: '#ff0000',
        opacity: 1,
        lineWidth: 8,
        outlineColor: '#ffffff',
        outlineWidth: 2
      }}
      clampToGround={true}
    />
    <GeoJSONPolygon
      data={geojsonPolygonData}
      style={{
        fillColor: '#ff0000',
        fillOpacity: 0.5,
        outlineColor: '#000000',
        outlineWidth: 2
      }}
    />
    <Mvt
      url={mvtUrl}
      layerName={mvtLayer}
      strokeStyle="#0080ff"
      fillStyle="#00ff80"
      lineWidth={3}
      onSelectFeature={(feature) => console.log('MVT feature selected:', feature)}
    />
  </Viewer>
</div>
0.0.12

3 months ago

0.0.1

4 months ago