異体字リストを取得するためのAPIの試作

概要 以下のページで「史料編纂所データベース異体字同定一覧」が公開されています。 https://wwwap.hi.u-tokyo.ac.jp/ships/itaiji_list.jsp 今回は、上記のページで公開されているデータをJSON形式で取得するためのAPIを作成します。 開発したもの 以下のURLからアクセスいただけます。 https://hi-itaiji.vercel.app/ 同定一覧における「char(異体字)」をキーとして、「base」の漢字を値とするマッピングを返却します。 まとめ 異体字リストの応用にあたり、参考になりましたら幸いです。

2025年2月10日 · 1 分 · Nakamura

Next 15(React 19 を使用)で、@react-three/fiberとdreiを使う

概要 Next 15(React 19 を使用)で、@react-three/fiberを使う際、以下のように説明されています。 R3F v8 is not compatible with React 19 or Next 15, which uses React 19. Use the R3F v9 RC instead which can be installed with @react-three/fiber@rc. (日本語訳)R3F v8 は React 19 や Next 15(React 19 を使用)と互換性がありません。代わりに R3F v9 RC を使用してください。インストールするには @react-three/fiber@rc を使用してください。 一方、マウス操作を行うために以下を追加しましたが、@react-three/fiber@rcとは相性が悪いようでした。 https://www.npmjs.com/package/@react-three/drei この問題に対する対処法の備忘録です。 方法 本記事執筆時点(2025-02-06)の情報です。 まず、@react-three/fiber@rcではなく、@react-three/fiber@alphaをインストールする必要がありました。(@betaでもよいかもしれません。) そして、dreiについては、@react-three/drei@10.0.0-rc.1をインストールしました。結果、以下のような組み合わせでは、無事にインストールすることができました。 "@react-three/drei": "^10.0.0-rc.1", "@react-three/fiber": "^9.0.0-alpha.8", まとめ 考慮が不十分な点があるかもしれませんが、参考になりましたら幸いです。

2025年2月6日 · 1 分 · Nakamura

Omeka Sにサイズが大きいファイルをアップロードする

概要 Omeka Sに比較的サイズが大きい(200MB超)ファイルをアップロードする機会がありましたので、備忘録です。 具体的には、3Dモデルを保存するために使用される3次元ファイル形式の.glbファイルをアップロードします。 課題 通常、比較的サイズが大きいファイルをGUIからアップロードを試みると、 以下のように「POST request exceeded maximum size」となることがあります。 これを対応方法の例を紹介します。 php.ini の設定変更 Omeka SはPHPの設定によってアップロードサイズの制限を受けるため、まずは php.ini の設定を確認・変更してください。 upload_max_filesize = 512M post_max_size = 512M max_execution_time = 300 変更後はWebサーバー(ApacheやNginx)を再起動してください。ただし、デメリットとして共有ホスティングでは変更できない場合などがあります。 直接サーバにアップロード Omeka SのGUIを経由せずに、サーバに直接ファイルをアップロードし、Omeka Sに認識させる方法もあります。 File Sideloadモジュール 以下で紹介したFile Sideloadモジュールが使用できます。 上記は一括登録の例ですが、以下のように「サイドロード:公式サイト以外からのファイル読込」オプションを使用して、サーバ上にアップロード済みのファイルを選択して登録することができます。 URL指定 サーバ上にアップロードしたファイルにURLでアクセスできる場合には、Omeka Sの標準機能を用いて登録することができます。 どの方法を選ぶべきか? 方法 メリット デメリット php.ini 設定変更 すぐに対応可能 共有ホスティングでは変更不可の場合あり File Sideloadモジュール GUI制限を回避 モジュールのインストールが必要 URL指定 一括登録が可能 URLの準備が必要 まとめ 他にも良い方法があるかもしれませんが、参考になりましたら幸いです。

2025年2月5日 · 1 分 · Nakamura

IIIFマニフェストファイルからOCR結果を含むTEI_XMLファイルを作成するプログラム

概要 IIIFマニフェストファイルからOCR結果を含むTEI_XMLファイルを作成するプログラムを作成しました。このプログラムの使用方法について説明します。 仕組み IIIFマニフェストファイルのURLを指定して、NDL古典籍OCR-LiteによるOCR結果を含むTEI/XMLファイルを作成します。 https://github.com/ndl-lab/ndlkotenocr-lite 使い方 以下のノートブックにアクセスしてください。 https://colab.research.google.com/github/nakamura196/000_tools/blob/main/IIIFマニフェストファイルからTEI_XMLファイルを作成するプログラム.ipynb そして、一つ目の再生ボタンを押します。 完了したら、「実行」という部分のmanifest_urlとoutput_dirの値を更新して、セルを実行します。 output_dirに、OCR結果を含むTEI/XMLファイルが出力されます。 出力例 以下のように、ページおよび行ごとのOCR結果を含むファイルが作成されます。 <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <TEI xmlns="http://www.tei-c.org/ns/1.0"> <teiHeader> <fileDesc> <titleStmt> <title>OCR結果: https://iiif.dl.itc.u-tokyo.ac.jp/repo/iiif/0f11a3ed-18c2-7322-6340-19ed3f0d966e/manifest</title> </titleStmt> <publicationStmt> <publisher>NDL古典OCR</publisher> <date>2025-01-29</date> </publicationStmt> <sourceDesc> <bibl> <ptr target="https://iiif.dl.itc.u-tokyo.ac.jp/repo/iiif/0f11a3ed-18c2-7322-6340-19ed3f0d966e/manifest"/> </bibl> </sourceDesc> </fileDesc> </teiHeader> <text> <body> <ab n="1" type="page" facs="https://iiif.dl.itc.u-tokyo.ac.jp/iiif/soto_ogai_202310/A05_4/002/A05_4_002_0001.tif/full/full/0/default.jpg"> <lb/> <seg type="本文" n="1" corresp="#zone-1">国外</seg> <lb/> <seg type="本文" n="3" corresp="#zone-3">空せみ二</seg> <lb/> <seg type="本文" n="4" corresp="#zone-4">ゆふかほ</seg> </ab> <ab n="2" type="page" facs="https://iiif.dl.itc.u-tokyo.ac.jp/iiif/soto_ogai_202310/A05_4/002/A05_4_002_0002.tif/full/full/0/default.jpg"> <lb/> <seg type="本文" n="1" corresp="#zone-1">あつたい</seg> <lb/> <seg type="本文" n="2" corresp="#zone-2">・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・</seg> <lb/> <seg type="本文" n="3" corresp="#zone-3">中川ノ中川宿にて之源氏十六才</seg> <lb/> <seg type="本文" n="4" corresp="#zone-4">住ぬ</seg> <lb/> <seg type="本文" n="5" corresp="#zone-5">ねられ給はぬまゝに。われはかく人に</seg> <lb/> <seg type="本文" n="6" corresp="#zone-6">にくまれてもならはぬを。こよひなん</seg> <lb/> <seg type="本文" n="7" corresp="#zone-7">はじめてうしと世を思ひ知ぬれば</seg> <lb/> <seg type="本文" n="8" corresp="#zone-8">はつかしうてながらふまじくこそ思ひ</seg> <lb/> <seg type="本文" n="9" corresp="#zone-9">なりぬれなどの給へば。なみたをさへ</seg> <lb/> <seg type="本文" n="10" corresp="#zone-10">こぼしてふしたり。いどらうたしと</seg> <lb/> <seg type="本文" n="11" corresp="#zone-11">おぼすてさぐりのほそくちいさき</seg> <lb/> <seg type="本文" n="12" corresp="#zone-12">ほどがみのいとながからざりしけ</seg> <lb/> まとめ 不完全な点もあるかと思いますが、参考になりましたら幸いです。 ...

2025年1月30日 · 1 分 · Nakamura

校異源氏物語に対する類似テキスト検索アプリを作成しました。

概要 校異源氏物語に対する類似テキスト検索アプリを作成しました。以下のURLからお試しいただけます。 https://huggingface.co/spaces/nakamura196/genji_predict 本アプリの使用方法などについて紹介します。 データ 以下の校異源氏物語DBで公開されているテキストデータを使用します。 https://kouigenjimonogatari.github.io/ アプリの内容 仕組みは単純で、校異源氏物語の巻毎・ページ毎のテキストを用意しておき、入力された文字列との編集距離を算出し、類似度が高いテキスト(+巻とページ)を返却します。 ソースコードは以下です。 https://huggingface.co/spaces/nakamura196/genji_predict/tree/main 応用例 例えば、以下の「[源氏物語] [4](東京大学総合図書館所蔵)」では、1つのIIIFマニフェスト内に複数の巻が含まれており、何コマ目から何コマ目までが何巻に属するのか、素人には判断が難しい場合があります。 https://da.dl.itc.u-tokyo.ac.jp/portal/assets/b90bbddc-509d-7c12-0fb9-af409a90a487 そこで、上記に資料に対してコマ毎のOCRテキストを取得し、今回作成したアプリに問い合わせることで、ページ毎に推定される巻数が提示され、巻の変わり目を知る手助けを行うことができます。 OCR OCRにあたっては、NDL古典籍OCR-Liteを使用します。 https://github.com/ndl-lab/ndlkotenocr-lite OCR結果を修正して、以下のようなTEI/XMLを作成しました。 <?xml version="1.0" encoding="UTF-8"?> <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <TEI xmlns="http://www.tei-c.org/ns/1.0"> <teiHeader> <fileDesc> <titleStmt> <title>OCR結果: https://iiif.dl.itc.u-tokyo.ac.jp/repo/iiif/b90bbddc-509d-7c12-0fb9-af409a90a487/manifest</title> </titleStmt> <publicationStmt> <publisher>NDL古典籍OCR-Lite</publisher> <date>2025-01-29</date> </publicationStmt> <sourceDesc> <bibl> <ptr target="https://iiif.dl.itc.u-tokyo.ac.jp/repo/iiif/b90bbddc-509d-7c12-0fb9-af409a90a487/manifest"/> </bibl> </sourceDesc> </fileDesc> </teiHeader> <text> <body> <ab n="1" type="page" facs="https://iiif.dl.itc.u-tokyo.ac.jp/iiif/soto_ogai_202310/A05_4/004/A05_4_004_0001.tif/full/full/0/default.jpg"> <lb/> <seg type="本文" n="1" corresp="#zone-1-1">国外</seg> <lb/> <seg type="本文" n="3" corresp="#zone-1-3">紅葉のか</seg> <lb/> <seg type="本文" n="4" corresp="#zone-1-4">はなのえん</seg> <lb/> <seg type="本文" n="5" corresp="#zone-1-5">あふひ</seg> </ab> <ab n="2" type="page" facs="https://iiif.dl.itc.u-tokyo.ac.jp/iiif/soto_ogai_202310/A05_4/004/A05_4_004_0002.tif/full/full/0/default.jpg"> <lb/> <seg type="本文" n="1" corresp="#zone-2-1">OOO</seg> <lb/> <seg type="本文" n="2" corresp="#zone-2-2">□□□□□□□□</seg> <lb/> <seg type="本文" n="3" corresp="#zone-2-3">源氏十七才ノ十月より四年の十月迄有</seg> <lb/> <seg type="本文" n="4" corresp="#zone-2-4">/朱雀院の行幸ば。神無月の十日</seg> <lb/> <seg type="本文" n="5" corresp="#zone-2-5">あまりなり。よのつねならず。おもし</seg> <lb/> <seg type="本文" n="6" corresp="#zone-2-6">ろかるべきたびのこと成ければ。御</seg> <lb/> <seg type="本文" n="7" corresp="#zone-2-7">かた〴〵物見給はぬことを口おし</seg> <lb/> <seg type="本文" n="8" corresp="#zone-2-8">がり給。うへもなつぼの。み給はざらん</seg> <lb/> <seg type="本文" n="9" corresp="#zone-2-9">をあかずおぼさるれば。誠楽を御</seg> <lb/> <seg type="本文" n="10" corresp="#zone-2-10">前にてせさせ給ふ。源氏の中将は。</seg> <lb/> <seg type="本文" n="11" corresp="#zone-2-11">青海波をぞまひ給ける。かたてには。</seg> <lb/> <seg type="本文" n="12" corresp="#zone-2-12">火とのゝ頭中将がたちようい人にこ</seg> <lb/> <seg type="本文" n="13" corresp="#zone-2-13">となるを。立ならびては。花のかたはらの</seg> <lb/> <seg type="本文" n="14" corresp="#zone-2-14">みやまばなり。入がたの日かげさやか</seg> <lb/> <seg type="本文" n="15" corresp="#zone-2-15">にさしたるに。がくのこゑまさり。物の</seg> <lb/> <seg type="本文" n="16" corresp="#zone-2-16">おもしろきほどに。おなじまひのあ</seg> <lb/> <seg type="本文" n="17" corresp="#zone-2-17">しぶみおもゝち。よに見えぬさまなり。</seg> <lb/> <seg type="本文" n="18" corresp="#zone-2-18">詠などし給へるはこれや仏の御迦</seg> <lb/> <seg type="本文" n="19" corresp="#zone-2-19">一後順伽のこゑならんと聞ゆ。おもし</seg> </ab> <ab n="3" type="page" facs="https://iiif.dl.itc.u-tokyo.ac.jp/iiif/soto_ogai_202310/A05_4/004/A05_4_004_0003.tif/full/full/0/default.jpg"> <lb/> <seg type="本文" n="1" corresp="#zone-3-1">ろく哀なるに。みかと泪おとし給。</seg> <lb/> <seg type="本文" n="2" corresp="#zone-3-2">上達部みこたちもみななき給ぬ</seg> <lb/> <seg type="本文" n="3" corresp="#zone-3-3">詠はてゝ初うちなをし給へるにま</seg> <lb/> <seg type="本文" n="4" corresp="#zone-3-4">ちとりたるがくのにぎはゝしきに</seg> <lb/> <seg type="本文" n="5" corresp="#zone-3-5">かほの色あひまさりてつねよりも</seg> <lb/> <seg type="本文" n="6" corresp="#zone-3-6">ひかると見え給。春宮の女御。かく</seg> 推定 上記のXMLファイルを入力として、先に紹介したGradioアプリのAPIを利用します。 ...

2025年1月29日 · 3 分 · Nakamura

Omeka SのImage ServerでのCORS対応

概要 Omeka SのImage ServerでのCORS対応に関する備忘録です。 背景 以下の記事で、Omeka SのIIIF ServerモジュールでのCORSエラーへの対応方法を紹介しました。 上記の設定により、IIIFマニフェストファイルはダウンロードできるようになりましたが、以下のように、画像がダウンロードできなくなるケースがありました。 Access to image at 'https://xxx/iiif/2/8455/full/86,/0/default.jpg' from origin 'https://uv-v4.netlify.app' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. この症状への対処方法について紹介します。 方法 複数の箇所にaccess-control-allow-originが記載されていることが原因です。 上記の記事の対応により、サイト全体に対してCORSの設定を行いましたので、Image Serverモジュールにおける設定が適用されないように修正します。なお、このような対応が必要なものは特定のバージョンのモジュールで、最新のモジュールなどを使用する場合には不要かもしれません。 具体的には、以下のファイルに記載されています。 https://github.com/Daniel-KM/Omeka-S-module-ImageServer/blob/master/src/Controller/ImageController.php 以下のように記載されており、条件によって適用の可否が設定されていますが、使用しているバージョンや他のモジュールとの組み合わせにより、この条件が適用されず、複数のaccess-control-allow-originが設定されてしまうことが原因かと思われます。 $headers->addHeaderLine('Access-Control-Allow-Origin', '*'); 上記のような記載をコメントアウトすることにより、'Access-Control-Allow-Origin' header contains multiple values '*, *'というエラーを解消することができました。 まとめ 同様の事象の遭遇することは稀かもしれませんが、Omeka Sを用いたIIIF画像配信にあたり、参考になりましたら幸いです。

2025年1月27日 · 1 分 · Nakamura

Alfrescoのファイルに対して、Archivematicaを使ってAIPを作成する

概要 Alfrescoのファイルに対して、Archivematicaを使ってAIPを作成する方法の一例です。 以下が成果物のデモ動画です。 https://youtu.be/7WCO7JoMnWc システム構成 今回は以下のようなシステム構成とします。複数のクラウドサービスを利用していることに特に意味はありません。 Alfrescoは、以下の記事を参考に、Azure上に構築したものを使用します。 Archivematicaとオブジェクトストレージはmdx.jpを使用し、分析環境はGakuNin RDMを使用します。 オブジェクトストレージへのファイルアップロード Alfrescoからファイルをダウンロード Alfrescoからのファイルダウンロードにあたっては、REST APIを使用します。 https://docs.alfresco.com/content-services/6.0/develop/rest-api-guide/ OpenAPIに準拠しており、以下などを参考にしました。 https://api-explorer.alfresco.com/api-explorer/ 例えば以下により、Alfrescoのユーザ名とパスワード、およびホスト名を環境変数から読み込み、メタデータの取得やコンテンツのダウンロードを行うことができました。 # %% ../nbs/00_core.ipynb 3 from dotenv import load_dotenv import os import requests from base64 import b64encode # %% ../nbs/00_core.ipynb 4 class ApiClient: def __init__(self, verbose=False): """Alfresco API Client Args: verbose (bool): デバッグ情報を出力するかどうか """ self.verbose = verbose # .envの読み込み load_dotenv(override=True) # 環境変数の取得 self.user = os.getenv('ALF_USER') self.password = os.getenv('ALF_PASSWORD') self.target_host = os.getenv('ALF_TARGET_HOST') self._debug("環境変数の設定:", { "user": self.user, "password": "*" * len(self.password) if self.password else None, "target_host": self.target_host }) # Basic認証のヘッダーを作成 credentials = f"{self.user}:{self.password}" encoded_credentials = b64encode(credentials.encode()).decode() self.headers = { 'accept': 'application/json', 'authorization': f'Basic {encoded_credentials}' } self._debug("ヘッダーの設定:", { "accept": self.headers['accept'], "authorization": "Basic ***" }) def _debug(self, message: str, data: dict = None): """デバッグ情報を出力する Args: message (str): メッセージ data (dict, optional): 追加のデータ """ if self.verbose: print(f"🔍 {message}") if data: for key, value in data.items(): print(f" - {key}: {value}") def get_nodes_nodeId(self, node_id: str): """ノードIDでノード情報を取得する Args: node_id (str): ノードID Returns: dict: ノード情報 """ url = f"{self.target_host}/alfresco/api/-default-/public/alfresco/versions/1/nodes/{node_id}" self._debug("APIリクエスト:", {"url": url}) try: response = requests.get( url, headers=self.headers, timeout=float(30) ) response.raise_for_status() return response.json() except requests.exceptions.Timeout: self._debug("エラー:", {"type": "timeout", "message": "リクエストがタイムアウトしました"}) return None except requests.exceptions.RequestException as e: self._debug("エラー:", {"type": "request", "message": str(e)}) return None def get_nodes_nodeId_content(self, node_id: str, output_path: str): """ノードのコンテンツを取得する Args: node_id (str): ノードID output_path (str): 出力パス """ url = f"{self.target_host}/alfresco/api/-default-/public/alfresco/versions/1/nodes/{node_id}/content" self._debug("APIリクエスト:", { "url": url, "output_path": output_path }) response = requests.get(url, headers=self.headers) binary_data = response.content os.makedirs(os.path.dirname(output_path), exist_ok=True) with open(output_path, "wb") as file: file.write(binary_data) self._debug("ファイル保存完了:", { "size": len(binary_data), "path": output_path }) オブジェクトストレージにファイルをアップロード boto3と、オブジェクトストレージのENDPOINT_URL、ACCESS_KEY、SECRET_KEYおよびBUCKET_NAMEなどを使用して、ファイルのアップロード(とダウンロード)を行います。 ...

2025年1月26日 · 3 分 · Nakamura

Alfresco Governance Services Community Editionを起動する

概要 以下のマニュアルを参考に、Alfresco Governance Services Community Editionのインストールを試みましたので、備忘録です。 https://support.hyland.com/r/Alfresco/Alfresco-Governance-Services-Community-Edition/23.4/Alfresco-Governance-Services-Community-Edition 参考 同様の取り組みとして、以下があります。こちらも参考にしてください。 https://irisawadojo.blogspot.com/2020/11/72alfresco2.html 仮想マシン 以下のマシンをAzureの仮想マシンとして作成しました。 イメージ: Ubuntu Server 24.04 LTS - Gen2 VM アーキテクチャ: x64 サイズ: Standard D2ads v6 (2 vcpu 数、8 GiB のメモリ) 8080ポートを使用するために、ポートを開けておきます。 Dockerのインストール Dockerをインストールします。 sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg # Docker の公式 GPG キーを追加 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc > /dev/null sudo chmod a+r /etc/apt/keyrings/docker.asc # Docker のリポジトリを追加 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update # Docker をインストール sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # sudo なしで Docker を実行 sudo usermod -aG docker $USER newgrp docker # Docker の動作確認 docker run hello-world インストール 以下の「Install using Docker Compose」を使用します。 ...

2025年1月23日 · 3 分 · Nakamura

XSLTを使いながらTEI/XMLファイルを編集する

概要 XSLTを使いながらTEI/XMLファイルを編集する方法の一例を紹介します。 関連 以下の記事で、VSCodeの拡張機能を使いながら、XSLTの結果をプレビューする方法を紹介しました。 本記事では、上記の拡張機能を使用せず、より単純にXSLTを使いながらTEI/XMLファイルを編集する方法を紹介します。 拡張機能のインストール VSCodeで以下の拡張機能をインストールします。 Live Server https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer Scholarly XML https://marketplace.visualstudio.com/items?itemName=raffazizzi.sxml Auto Close Tag https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag 加えて、以下の2つの拡張機能が、Scholarly XMLにおいて推奨されています。ただ、私の使い方では不便になってしまう場面もあったので、とりあえず任意とします。 Auto Rename Tag https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag Close HTML/XML tag https://marketplace.visualstudio.com/items?itemName=Compulim.compulim-vscode-closetag ファイルのダウンロードなど 以下のサンプルリポジトリを対象にします。 https://github.com/nakamura196/tei-xml-xslt-vscode 以下により、ファイルをダウンロードします。そして、VSCodeで開きます。 git clone https://github.com/nakamura196/tei-xml-xslt-vscode code tei-xml-xslt-vscode そして、画面右下のGo Liveをクリックします。 デフォルトでは、http://127.0.0.1:5500/がブラウザで開かれ、以下のフォルダが表示されます。 そして、teiフォルダ内のexample1.xmlを開くと、以下のように表示されます。 http://127.0.0.1:5500/tei/example1.xml TEI/XMLファイルの編集 VSCodeでTEI/XMLファイルを編集します。 そして、ブラウザで開いているページを更新すると、編集内容が反映されます。 これを繰り返し、TEI/XMLファイルを編集しながらプレビュー結果を確認します。 ファイルの変更 example1.xmlをコピーすることにより、新規のファイルを作成することができます。 またxslファイルは以下のように相対パスで指定されています。 <?xml-stylesheet type="text/xsl" href="../xsl/make-CETEIcean.xsl"?> 新規にxslファイルを作成し、上記の相対パスを変更することにより、他のxslファイルを用いたXSLTを実行できます。 参考 VSCodeでTEI/XMLファイルを編集する場合、Github Copilotなどを使って、AIによるサジェストを受けることができます。 またCursorを使って、AIによるアシストを受けることもできます。XSLファイルの編集にあたっては、AIによるアシストが特に便利でした。 縦書きにしたい。のような自然言語で指示することにより、xslファイルを編集できました。 まとめ 上記の手順はあくまで一例ですが、TEI/XMLファイルの編集にあたり、参考になりましたら幸いです。

2025年1月23日 · 1 分 · Nakamura

DataverseのデータをArchivematicaで処理する

概要 DataverseのデータをArchivematicaで処理する流れを確認しましたので、備忘録です。 背景 ArchivematicaではDataverseのデータを入力する機能を提供しています。 https://www.archivematica.org/en/docs/archivematica-1.17/user-manual/transfer/dataverse/ 本機能について、以下の講演会で教えていただいたので、実際に試してみました。 https://www.kulib.kyoto-u.ac.jp/bulletin/1402322 Dataverse 以下の記事でも使用したDemo Dataverseを使用します。 以下のデータをアップロードしました。 https://demo.dataverse.org/dataset.xhtml?persistentId=doi:10.70122/FK2/IHQZL3 ここから画像データそのものと、JSONデータをダウンロードします。Metadataタブに移動し、Export MetadataからJSONを選択します。 以下はJSONファイルの一部ですが、metadataBlocksにメタデータ、filesに画像ファイルの情報が記載されています。 { "metadataBlocks": { "citation": { "displayName": "Citation Metadata", "name": "citation", "fields": [ { "typeName": "title", "multiple": false, "typeClass": "primitive", "value": "nakamura196" }, { "typeName": "author", "multiple": true, "typeClass": "compound", "value": [ { "authorName": { "typeName": "authorName", "multiple": false, "typeClass": "primitive", "value": "Nakamura, Satoru" }, "authorAffiliation": { "typeName": "authorAffiliation", "multiple": false, "typeClass": "primitive", "value": "https://ror.org/057zh3y96", "expandedvalue": { "scheme": "http://www.grid.ac/ontology/", "termName": "The University of Tokyo", "@type": "https://schema.org/Organization" } } } ] }, { "typeName": "datasetContact", "multiple": true, "typeClass": "compound", "value": [ { "datasetContactName": { "typeName": "datasetContactName", "multiple": false, "typeClass": "primitive", "value": "Nakamura, Satoru" }, "datasetContactEmail": { "typeName": "datasetContactEmail", "multiple": false, "typeClass": "primitive", "value": "na.kamura.1263@gmail.com" } } ] }, { "typeName": "dsDescription", "multiple": true, "typeClass": "compound", "value": [ { "dsDescriptionValue": { "typeName": "dsDescriptionValue", "multiple": false, "typeClass": "primitive", "value": "My First Dataset" } } ] }, { "typeName": "subject", "multiple": true, "typeClass": "controlledVocabulary", "value": [ "Arts and Humanities" ] }, { "typeName": "depositor", "multiple": false, "typeClass": "primitive", "value": "Nakamura, Satoru" }, { "typeName": "dateOfDeposit", "multiple": false, "typeClass": "primitive", "value": "2025-01-19" } ] } }, "files": [ { "label": "nakamura196.jpg", "restricted": false, "version": 1, "datasetVersionId": 281093, "dataFile": { "id": 2514724, "persistentId": "doi:10.70122/FK2/IHQZL3/B7JVQS", "pidURL": "https://doi.org/10.70122/FK2/IHQZL3/B7JVQS", "filename": "nakamura196.jpg", "contentType": "image/jpeg", "friendlyType": "JPEG Image", "filesize": 53656, "storageIdentifier": "s3://demo-dataverse-org:1948154820d-63733533ea7c", "rootDataFileId": -1, "md5": "72f08a8b07bacbe3b5cf021910fd26dc", "checksum": { "type": "MD5", "value": "72f08a8b07bacbe3b5cf021910fd26dc" }, "tabularData": false, "creationDate": "2025-01-19", "publicationDate": "2025-01-19", "fileAccessRequest": true } } ] } データの準備 Dataverseのサンプルデータは以下に格納されています。 ...

2025年1月21日 · 2 分 · Nakamura

VSCodeとXSLTを用いたTEI/XMLのリアルタイムプレビュー

概要 VSCodeとXSLTを用いたTEI/XMLのリアルタイムプレビュー環境を試作したので、備忘録です。 挙動 動作例は以下です。TEI/XMLファイルを編集し、保存すると、ブラウザの表示内容が更新されます。 https://youtu.be/ZParCRUc5AY?si=-aHHi3bIZGWoJYnP 準備 以下の拡張機能をインストールします。 Live Server Trigger Task on Save TEI/XMLを保存した際に、Trigger Task on SaveによってXSLTを実行し、変換されたHTMLファイルをLive Serverで閲覧します。 リポジトリ サンプルコードを以下に格納しています。 https://github.com/nakamura196/tei-xml-xslt-vscode XSLTを行うにあたり、xslt3をインストールします。 git clone https://github.com/nakamura196/tei-xml-xslt-vscode cd tei-xml-xslt-vscode npm install settings.jsonとtasks.json .vscodeフォルダに、settings.jsonとtasks.jsonを格納しています。 tasks.jsonは以下です。xsl/make-CETEIcean.xslを用いて、XSLTを行うタスクを設定しています。 { "version": "2.0.0", "tasks": [ { "label": "Transform XML with XSLT", "type": "shell", "command": "npx", "args": [ "xslt3", "-xsl:xsl/make-CETEIcean.xsl", "-s:${file}", "-o:${fileDirname}/${fileBasenameNoExtension}.html" ], "presentation": { "reveal": "never", "close": true }, "group": { "kind": "build", "isDefault": true }, "problemMatcher": [] } ] } xsl/make-CETEIcean.xslは、CETEIceanで公開されているXSLファイルです。 https://github.com/TEIC/CETEIcean/blob/master/xslt/make-CETEIcean.xsl 次に、settings.jsonです。teiフォルダ以下のxmlファイルに対して、保存時に上記のタスクを実行します。 { "triggerTaskOnSave.tasks": { "Transform XML with XSLT": ["tei/*.xml"] } } これらの設定により、TEI/XMLファイルを保存時に、同フォルダにHTMLファイルが作成されます。 ...

2025年1月15日 · 3 分 · Nakamura

校異源氏物語テキストDBのTEI/XMLからPDFを作成する

概要 校異源氏物語テキストDBは、『校異源氏物語』のテキストデータを公開するデータベースです。 https://kouigenjimonogatari.github.io/ 今回、本DBに以下のようなPDFファイルを追加しました。 https://kouigenjimonogatari.github.io/output/01/main.pdf 本記事は、上記のようなPDFファイルを、XSLTとTeXを使って作成します。 リポジトリのクローン 以下のように、リポジトリをクローンします。 git clone --depth 1 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io そして以下のコマンドにより、xslt3をインストールします。 npm i xslt3 https://www.npmjs.com/package/xslt3 XSLファイルの作成 今回は、まずTEI/XMLファイルをTeXファイルに変換します。 以下のようなXSLファイルを作成しました。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/xsl/tex.xsl <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> \documentclass[a4paper,11pt,landscape]{ltjtarticle} \usepackage{xcolor} \usepackage{luatexja-fontspec} % fontspec を LuaTeX-ja と共に利用 \usepackage[top=2cm,bottom=2cm,left=2cm,right=2cm,textwidth=25cm]{geometry} % スタイル定義 \newcommand{\person}[1]{\textbf{\color{blue}#1}} \newcommand{\place}[1]{\textit{\color{green}#1}} % 日本語フォント設定 \setmainjfont{Noto Serif CJK JP} % 日本語フォントを指定 \title{<xsl:value-of select="//tei:title"/>} \date{} \begin{document} \maketitle % 本文 <xsl:for-each select="//tei:seg"> <xsl:apply-templates/> \par\medskip </xsl:for-each> \end{document} </xsl:template> <!-- 人名の処理 --> <xsl:template match="tei:persName"> \person{<xsl:value-of select="."/>}</xsl:template> <!-- 地名の処理 --> <xsl:template match="tei:placeName"> \place{<xsl:value-of select="."/>}</xsl:template> </xsl:stylesheet> 先にインストールしたxslt3を使って、以下のようにTEI/XMLファイルをTeXファイルに変換できます。 ...

2025年1月14日 · 1 分 · Nakamura

@sidebase/nuxt-authのローカル認証を試す

概要 @sidebase/nuxt-authのローカル認証を試す機会がありましたので、備忘録です。 背景 以下の記事で、@sidebase/nuxt-authを使って、Drupalの認証を行う方法を紹介しました。 上記の記事では、Nuxt3のSSRを利用して、@sidebase/nuxt-authのauthjsプロバイダを使用していました。プロバイダの説明は以下です。 authjs: for non-static apps that want to use Auth.js / NextAuth.js to offer the reliability & convenience of a 23k star library to the Nuxt 3 ecosystem with a native developer experience (DX) local: for static pages that rely on an external backend with a credential flow for authentication. The Local Provider also supports refresh tokens since v0.9.0. Read more here. (機械翻訳)authjs: 非静的なアプリ向けで、Auth.js / NextAuth.js を使用し、23,000以上のスターを持つ信頼性と利便性をNuxt 3エコシステムに提供します。開発者にネイティブな開発体験 (DX) を提供します。 local: 外部バックエンドを使用し、認証のために資格情報フローを利用する静的ページ向けです。このローカルプロバイダーは、バージョン0.9.0以降、リフレッシュトークンもサポートしています。詳しくはこちらをご覧ください。 ...

2025年1月13日 · 2 分 · Nakamura

Nuxt3と@sidebase/nuxt-authを使って、Drupalの認証を行う

概要 Nuxt3と@sidebase/nuxt-authを使って、Drupalの認証を行う方法です。 背景 以下の記事で、GakuNin RDMの認証を行う方法を紹介しました。 また、以下の記事で、Next.jsからDrupalのOAuthを利用する方法を紹介しました。 これらを参考にして、Nuxt3からDrupalのOAuthを利用します。 方法 ソースコードは以下のリポジトリでご確認いただけます。 https://github.com/nakamura196/nuxt-rdm 具体的には、以下です。 https://github.com/nakamura196/nuxt-rdm/blob/main/server/api/auth/[…].ts { id: "drupal", name: "Drupal", type: "oauth", clientId: useRuntimeConfig().drupalClientId, clientSecret: useRuntimeConfig().drupalClientSecret, authorization: { url: process.env.DRUPAL_AUTH_URL, params: { scope: process.env.DRUPAL_SCOPE, response_type: "code", redirect_uri: `${ useRuntimeConfig().nextAuthUrl }/api/auth/callback/drupal`, }, }, token: { async request(context) { const body = new URLSearchParams({ client_id: useRuntimeConfig().drupalClientId, client_secret: useRuntimeConfig().drupalClientSecret, code: context.params.code || "", grant_type: "authorization_code", redirect_uri: `${ useRuntimeConfig().nextAuthUrl }/api/auth/callback/drupal`, }); const res = await fetch(process.env.DRUPAL_TOKEN_URL || "", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body, }); const json = await res.json(); // Parse the response body once if (!res.ok) { throw new Error(`Token request failed: ${res.statusText}`); } return { tokens: json }; }, }, profile(profile) { return { id: profile.sub, // "sub" をユーザーの一意のIDとして利用 name: profile.name || profile.preferred_username || "Unknown User", // 名前の優先順位を設定 email: profile.email || "No Email Provided", // メールがない場合のフォールバック image: profile.profile || null, // プロファイルURLを画像として使用(必要に応じて調整) }; }, }, まとめ 間違っている点もあるかもしれませんが、参考になりましたら幸いです。 ...

2025年1月12日 · 1 分 · Nakamura

Omeka S: Advanced Searchモジュールに対応したテーマを探す

概要 Omeka SのAdvanced Searchモジュールに対応したテーマを探す方法の一例について紹介します。 背景 Omeka SのAdvanced Searchモジュールを用いることで、以下の記事などで紹介しているように、Omeka Sの検索画面をカスタマイズすることができます。 特に、ファセットなどを追加できる点に利点があります。 一方、使用しているテーマがこのAdvanced Searchモジュールに対応していない場合、一部表示が崩れてしまうケースがあります。テーマ側でAdvanced Searchモジュールに対応しているかどうかを判断する方法の一例として、以下のように、テーマのフォルダの「view/common」の下に「advanced-search」の有無を確認する方法があります。 https://github.com/omeka-s-themes/freedom/tree/master/view/common/advanced-search この方法に基づいて、GitHubで公開されているOmeka Sのテーマのうち、Advanced Searchモジュールに対応しているものを探す方法を紹介します。 方法 以下の記事で紹介したサイトを使用します。 URLは以下です。 https://satoru196.notion.site/satoru196/6f898ed1352e4c9fa013eee635cbabf4?v=02cab757b6cf4df6bfbedfeb85eca0a5 特に、本記事の目的のため、「各テーマがAdvanced Searchモジュールに対応しているか」のフラグを追加しました。加えて、リポジトリのownerの情報も加え、各テーマが誰によって提供されているかを確認できるようにしました。 具体的には、以下の図に示すように、スター数で降順として、さらに「has_advanced_search」にチェックが入っているテーマのみに限定します。 この結果、「freedom」というテーマが「omeka-s-themes」というOmekaの公式Teamによって提供されており、相対的にスター数が多く、Advanced Searchモジュールにも対応していることがわかります。 https://github.com/omeka-s-themes/freedom まとめ Omeka Sのテーマの探し方の一例について紹介しました。Omeka Sの利用にあたり、参考になりましたら幸いです。

2025年1月11日 · 1 分 · Nakamura

NextAuth.jsを使ってDrupalのOAuthを利用する

概要 NextAuth.jsを使ってDrupalのOAuthを利用する方法に関する備忘録です。 挙動 Next.jsで作成したアプリにアクセスして、「Sign in」ボタンを押します。 Drupalにログインしていない場合には、ログイン画面に遷移します。 ログイン済みの場合、「許可」するかのボタンが表示されるので、許可します。 ログイン情報が表示されます。 Drupal側の準備 モジュールのインストール 以下のモジュールをインストールします。 https://www.drupal.org/project/simple_oauth 本記事執筆時点の最新の以下をインストールしました。 composer require 'drupal/simple_oauth:^6.0@beta' トークンを暗号化するための鍵の生成 鍵のペアを生成し、セキュリティのためにドキュメントルートの外に保存します。 openssl genrsa -out private.key 2048 openssl rsa -in private.key -pubout > public.key 鍵のパスを設定 鍵のパスを管理画面で設定します: /admin/config/people/simple_oauth Amazon LightsailでDrupalを動作させている場合、以下のように、ユーザを変更する必要がありました。 sudo chown daemon:daemon private.key Clients /admin/config/services/consumerにアクセスします。 default_consumerがすでに作成されているため、こちらを編集します。 New Secretに値を入力します。 Grant typesでAuthorization Codeを選択します。 Redirect URIsに以下を入力します。 http://localhost:3000/api/auth/callback/drupal https://oauth.pstmn.io/v1/callback (Postmanでのチェック用) Access token expiration timeに値を入力します。 Postmanでの動作確認 以下のように入力します。Drupalがhttps://drupal.example.orgにセットアップされていると過程します。 認可 URL: https://drupal.example.org/oauth/authorize アクセストークン URL: https://drupal.example.org/oauth/token クライアント ID: Drupalで設定した値 クライアントシークレット: Drupalで設定した値 ...

2025年1月9日 · 2 分 · Nakamura

AppSheetを使ってデジタルコレクションを構築する

概要 AppSheetを使ってデジタルコレクションを試作してみましたので、備忘録です。 対象データ 以下の記事と同じデータを利用しています。 具体的には、『東京帝國大學本部構内及農學部建物鳥瞰圖』(東京大学農学生命科学図書館所蔵)をサンプルデータとして使用します。 https://iiif.dl.itc.u-tokyo.ac.jp/repo/s/agriculture/document/187cc82d-11e6-9912-9dd4-b4cca9b10970 成果物 以下のURLからアクセスいただけます。 https://www.appsheet.com/start/092a3ff4-1074-4e27-bbd1-f4820da77511 画像の一覧機能や、 地図へのマッピング機能、 簡単な集計機能を提供します。 作成方法 アプリの初期設定 アプリを作成します。 データソースとして、Google Sheetsを選択します。ちなみに、「AppSheet Database」を使用した場合、Free Planではデプロイできませんでした。 結果、デフォルトで地図表示、およびデータの一覧を表示するページ(View)を作成してくれました。 データ 「データ」タブに移動して、設定を行います。 例えば、使用しない項目には、「SHOW?」列のチェックを外します。また、「KEY?」と「LABEL?」に対して、「identifier」と「title」を割り当てました。 次に、「DISPLAY NAME」で、アプリ上で表示する名称を入力します。 さらに、検索に使用したい項目にのみ、「SEARCH?」列にチェックを入れます。 加えて、今回はデータの閲覧のみを行うため、「Read-Only」の設定を行います。 Views(マップ) Views(マップ)はデフォルトのまま使用しました。 Views(main) ここでは、View nameを「Browse」に変更して、View typeとして「card」を選択して、Positionには「next」を与えました。Positionについては、メニューにおいて「Browse」が「Map」の左にくるようになります。 さらに、レイアウトについて、それぞれの要素に割り当てるカラムを設定します。例えば以下では、画像を表示する列として、「_image_url」を指定しています。 結果、一覧画面が以下のように表示されます。 Views(chart) 以下のように、新規にViewを追加します。 そして、「Chart columns」に、ここではカテゴリが格納されたカラムを設定しました。結果、画面右部のように表示が変わります。 その他 その他、アプリの見た目を変更します。 設定 > Theme & Brand から、例えば、ヘッダーにロゴなどが表示されるように変更します。 また、今回の初期設定では「Map」Viewがはじめに開いてしまうので、「Browse」が表示されるように、「Views」の設定を変更します。 Preview ここまでのところでプロトタイプはほぼ完成です。Previewモードで確認することができます。デフォルトで、各レコードの詳細画面も表示されます。 ...

2025年1月8日 · 1 分 · Nakamura

Azure Logic Appsを試す

概要 ノーコードまたはローコード開発の調査を目的として、Azure Logic Appsを試してみましたので備忘録です。 成果物 以下は、ロジックアプリデザイナーの画面です。HTTPリクエストを受信し、Cosmos DBにデータを保存し、成功時にメールを送信するワークフローを作成します。 Azure Cosmos DBの作成 「アカウント名」以外はデフォルトにしました。「my-first-azure-cosmos-db-account」という名前で作成しました。 「Items」コンテナを作成します。 「データエクスプローラ」を使って、データベース「ToDoList」の下に、コレクション「Items」が作成されていることを確認できます。 ロジック アプリの作成 ロジック アプリの作成を行います。 「my-first-logic-app」を作成しました。 「ロジックアプリデザイナー」に移動します。 HTTPリクエスト まず、「Request」を選びます。 そして、以下を入力します。今回は単純に「url」と「code」という項目を管理します。 { "type": "object", "properties": { "url": { "type": "string" }, "code": { "type": "string" } }, "required": [ "url", "code" ] } Cosmos DBの追加 まずコネクションを作成します。 入力すべき値は、「Azure Cosmos DB アカウント」ページの「設定 > キー」から確認することができました。 次に、パラメータを入力します。先ほど作成したコレクション「Items」を選択して、「ドキュメント」に以下を入力します。 { "id": "@{guid()}", "url": "@{triggerBody()?['url']}", "code": "@{triggerBody()?['code']}" } idとしてUUIDを入力し、フォームから受け取ったurlとcodeをDBに登録します。 メールの送信 最後に、メールの送信設定です。今回は「Office 365 Outlook」の「メールの送信(V2)」を選択しました。 ...

2025年1月7日 · 1 分 · Nakamura

Azure OpenAI Assistants APIを用いたアプリをGradioとNext.jsで作成する

概要 Azure OpenAI Assistants APIを用いたアプリをGradioとNext.jsで作成したので、備忘録です。 対象データ Zennで公開している記事を対象にしました。まず以下により、一括ダウンロードしました。 import requests from bs4 import BeautifulSoup import os from tqdm import tqdm page = 1 urls = [] while 1: url = f"https://zenn.dev/api/articles?username=nakamura196&page={page}" response = requests.get(url) data = response.json() articles = data['articles'] if len(articles) == 0: break for article in articles: urls.append("https://zenn.dev" + article['path']) page += 1 for url in tqdm(urls): text_opath = f"data/text/{url.split('/')[-1]}.txt" if os.path.exists(text_opath): continue response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") html = soup.find(class_="znc") txt = html.get_text() os.makedirs(os.path.dirname(text_opath), exist_ok=True) with open(text_opath, "w") as f: f.write(txt) ベクトルストアへの登録 以下のようなコードにより、データファイルをアップロードします。 import os from dotenv import load_dotenv from openai import AzureOpenAI from glob import glob from tqdm import tqdm load_dotenv(override=True) client = AzureOpenAI( azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT_ZENN"), api_key=os.getenv("AZURE_OPENAI_API_KEY_ZENN"), api_version="2024-05-01-preview" ) # ベクトルストアの作成または取得 is_create_vector_store = True vector_store_name = "Vector Store" if is_create_vector_store: vector_store = client.beta.vector_stores.create(name=vector_store_name) # Create a vector store caled "Financial Statements" vector_stores = client.beta.vector_stores.list() for vector_store in vector_stores: if vector_store.name == vector_store_name: vector_store_id = vector_store.id break # 登録済みデータファイルの取得 response = client.files.list(purpose="assistants") items = response.data filenames = [] for item in items: filename = item.filename filenames.append(filename) filenames.sort() # アップロード ## 定数設定 BATCH_SIZE = 100 vector_store_id = "vs_UELnIBkcROD3o4XKX2CcpVjo" ## ファイル一覧取得とソート files = glob("./data/text/*.txt") files.sort() ## アップロード済みファイルを確認済みと仮定 file_streams = [] for file in tqdm(files): filename = os.path.basename(file) if filename in filenames: # アップロード済みのファイルをスキップ continue ## ファイルをストリームとして開く file_streams.append(open(file, "rb")) ## バッチサイズに達したらアップロード処理 if len(file_streams) == BATCH_SIZE: try: client.beta.vector_stores.file_batches.upload_and_poll( vector_store_id=vector_store_id, files=file_streams ) except Exception as e: print(f"Error processing batch: {e}") finally: file_streams = [] # ストリームリセット ## 残りのファイルを処理 if file_streams: try: client.beta.vector_stores.file_batches.upload_and_poll( vector_store_id=vector_store_id, files=file_streams ) except Exception as e: print(f"Error processing remaining files: {e}") アシスタント プレイグラウンド 「アシスタント プレイグラウンド」を用いて、挙動を確認します。 ...

2025年1月6日 · 2 分 · Nakamura

Kompakkt Standalone Viewerを試す

概要 Kompakkt Standalone Viewerを試す機会がありましたので、備忘録です。 以下のように説明されています。 This repository hosts a JavaScript file which can be included on any website to use the Kompakkt Viewer without needing to use the Kompakkt Repository or the Kompakkt Server. (機械翻訳)このリポジトリには、Kompakkt Viewerを使用するためのJavaScriptファイルが含まれており、このファイルをウェブサイトに組み込むだけで、Kompakkt RepositoryやKompakkt Serverを使用せずにビューアを利用することができます。 リポジトリ 以下で公開されています。 https://github.com/Kompakkt/StandaloneViewer またGitHub Pagesでビューアにアクセスすることができます。 https://kompakkt.github.io/StandaloneViewer/ 表示例 以下のように、3Dモデルとアノテーションを表示することができました。 https://kompakkt.github.io/StandaloneViewer/?state=eyJyZXNvdXJjZSI6Imh0dHBzOi8vc3VraWxhbS5hd3MubGRhcy5qcC9maWxlcy9vcmlnaW5hbC8yNTNlZmRmMzQ0Nzg0NTk5NTRhZTA0ZjZiM2JlZmE1ZjM4MjJlZDU5LmdsYiIsImFubm90YXRpb25zIjpbeyJfaWQiOiI2NzcwYTE1NDRjZTFmZDAyMzQ4OGVkODAiLCJib2R5Ijp7InR5cGUiOiJhbm5vdGF0aW9uIiwiY29udGVudCI6eyJ0eXBlIjoidGV4dCIsInRpdGxlIjoibXkgdGl0bGUiLCJkZXNjcmlwdGlvbiI6Im15IGRlc2NyaXB0aW9uIiwicmVsYXRlZFBlcnNwZWN0aXZlIjp7ImNhbWVyYVR5cGUiOiJhcmNSb3RhdGVDYW0iLCJwb3NpdGlvbiI6eyJ4IjoyLjI5NzE5OTgyNzA3MzIxLCJ5IjoxLjA0NjMzMzI0ODg4Njk0LCJ6IjoxLjYzNjAwODMyNDk5NDF9LCJ0YXJnZXQiOnsieCI6MS4wMTMxMDUwMzQ4MjgxOSwieSI6MS4xNzkwMzM5OTQ2NzQ2OCwieiI6MS4wMTQ0NDIwMjY2MTUxNH0sInByZXZpZXciOiJwcmV2aWV3cy9hbm5vdGF0aW9uLzY3NzBhMTU0NGNlMWZkMDIzNDg4ZWQ4MC5wbmcifX19LCJjcmVhdGVkIjoiMjAyNC0xMi0yOVQwMTowOTo0MC4yODZaIiwiY3JlYXRvciI6eyJ0eXBlIjoicGVyc29uIiwibmFtZSI6IlNhdG9ydSBOYWthbXVyYSIsIl9pZCI6IjY3NWE5Y2U0N2QxZmIyNDUzZjBmYjNjMSJ9LCJnZW5lcmF0ZWQiOiIyMDI0LTEyLTI5VDAxOjA5OjQyLjk3NFoiLCJnZW5lcmF0b3IiOnsidHlwZSI6InNvZnR3YXJlIiwibmFtZSI6IktvbXBha2t0IiwiX2lkIjoiNjc1YTljZTQ3ZDFmYjI0NTNmMGZiM2MxIiwiaG9tZXBhZ2UiOiJodHRwczovL2dpdGh1Yi5jb20vS29tcGFra3QvS29tcGFra3QifSwiaWRlbnRpZmllciI6IjY3NzBhMTU0NGNlMWZkMDIzNDg4ZWQ4MCIsImxhc3RNb2RpZmljYXRpb25EYXRlIjoiMjAyNC0xMi0yOVQwMToxMToyNC4zNjBaIiwibGFzdE1vZGlmaWVkQnkiOnsiX2lkIjoiNjc1YTljZTQ3ZDFmYjI0NTNmMGZiM2MxIiwibmFtZSI6IlNhdG9ydSBOYWthbXVyYSIsInR5cGUiOiJwZXJzb24ifSwibW90aXZhdGlvbiI6ImRlZmF1bHRNb3RpdmF0aW9uIiwicmFua2luZyI6MSwidGFyZ2V0Ijp7InNvdXJjZSI6eyJyZWxhdGVkRW50aXR5IjoiNjc3MDllODYwY2I4ZDA2NGZhMDc1NWI3IiwicmVsYXRlZENvbXBpbGF0aW9uIjoiIn0sInNlbGVjdG9yIjp7InJlZmVyZW5jZVBvaW50Ijp7Il9pc0RpcnR5Ijp0cnVlLCJfeCI6MC40MzI0MjIyMjQwNDc5MDksIl95IjoxLjY3NDQzMTE3MTYxNjA1LCJfeiI6MS42NTQ2MTgxODc1NDE1OH0sInJlZmVyZW5jZU5vcm1hbCI6bnVsbH19LCJ2YWxpZGF0ZWQiOnRydWV9XX0%253D ただし、アノテーションに日本語が含まれているとエラーが発生してしまいました。 また、アノテーションが3Dモデル上に表示されないなど、使用方法に誤りが含まれるようでした。 補足 入力するアノテーションのフォーマットとして、Kompakktで付与したアノテーションをエクスポートしたものが利用できるようでした。 例えば、以下です。 [ { "_id": "6770a1544ce1fd023488ed80", "body": { "type": "annotation", "content": { "type": "text", "title": "aaa", "description": "bbb", "relatedPerspective": { "cameraType": "arcRotateCam", "position": { "x": 2.29719982707321, "y": 1.04633324888694, "z": 1.6360083249941 }, "target": { "x": 1.01310503482819, "y": 1.17903399467468, "z": 1.01444202661514 }, "preview": "previews/annotation/6770a1544ce1fd023488ed80.png" } } }, "created": "2024-12-29T01:09:40.286Z", "creator": { "type": "person", "name": "Satoru Nakamura", "_id": "675a9ce47d1fb2453f0fb3c1" }, "generated": "2024-12-29T01:09:42.974Z", "generator": { "type": "software", "name": "Kompakkt", "_id": "675a9ce47d1fb2453f0fb3c1", "homepage": "https://github.com/Kompakkt/Kompakkt" }, "identifier": "6770a1544ce1fd023488ed80", "lastModificationDate": "2025-01-04T22:47:44.949Z", "lastModifiedBy": { "_id": "675a9ce47d1fb2453f0fb3c1", "name": "Satoru Nakamura", "type": "person" }, "motivation": "defaultMotivation", "ranking": 1, "target": { "source": { "relatedEntity": "67709e860cb8d064fa0755b7", "relatedCompilation": "" }, "selector": { "referencePoint": { "_isDirty": true, "_x": 0.432422224047909, "_y": 1.67443117161605, "_z": 1.65461818754158 }, "referenceNormal": null } }, "validated": true } ] ただし、Kompakktでも3Dモデル上にアノテーションが表示されず、使用方法のどこかに誤りがありそうです。 ...

2025年1月5日 · 1 分 · Nakamura