> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-1d264819.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> 店舗、レストラン、公園、遊び場、記念碑など、地図上のさまざまな場所に関する情報を含む、1億件超のレコードからなるデータセットです。

# Foursquareのスポット

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

<div id="dataset">
  ## データセット
</div>

この Foursquare のデータセットは、[ダウンロード](https://docs.foursquare.com/data-products/docs/access-fsq-os-places)して
Apache 2.0 ライセンスのもとで無料で利用できます。

店舗、レストラン、公園、遊び場、記念碑などの商業施設やスポット (POI) に関する
1億件を超えるレコードが含まれています。さらに、それらの場所に関する追加のメタデータとして、
カテゴリやソーシャルメディア情報も含まれています。

<div id="data-exploration">
  ## データの探索
</div>

データを探索するには、小規模なコマンドラインツールである [`clickhouse-local`](https://clickhouse.com/blog/extracting-converting-querying-local-files-with-sql-clickhouse-local) を使用します。これは ClickHouse engine の全機能を利用できますが、ClickHouse Cloud、`clickhouse-client`、あるいは `chDB` を使用することもできます。

データが保存されている S3 バケットからデータを取得するには、次のクエリを実行します。

```sql title="Query" theme={null}
SELECT * FROM s3('s3://fsq-os-places-us-east-1/release/dt=2025-04-08/places/parquet/*') LIMIT 1
```

```response title="Response" theme={null}
Row 1:
──────
fsq_place_id:        4e1ef76cae60cd553dec233f
name:                @VirginAmerica In-flight Via @Gogo
latitude:            37.62120111687914
longitude:           -122.39003793803701
address:             ᴺᵁᴸᴸ
locality:            ᴺᵁᴸᴸ
region:              ᴺᵁᴸᴸ
postcode:            ᴺᵁᴸᴸ
admin_region:        ᴺᵁᴸᴸ
post_town:           ᴺᵁᴸᴸ
po_box:              ᴺᵁᴸᴸ
country:             US
date_created:        2011-07-14
date_refreshed:      2018-07-05
date_closed:         2018-07-05
tel:                 ᴺᵁᴸᴸ
website:             ᴺᵁᴸᴸ
email:               ᴺᵁᴸᴸ
facebook_id:         ᴺᵁᴸᴸ
instagram:           ᴺᵁᴸᴸ
twitter:             ᴺᵁᴸᴸ
fsq_category_ids:    ['4bf58dd8d48988d1f7931735']
fsq_category_labels: ['Travel and Transportation > Transport Hub > Airport > Plane']
placemaker_url:      https://foursquare.com/placemakers/review-place/4e1ef76cae60cd553dec233f
geom:                �^��a�^@Bσ���
bbox:                (-122.39003793803701,37.62120111687914,-122.39003793803701,37.62120111687914)
```

かなり多くのフィールドが `ᴺᵁᴸᴸ` になっていることがわかるので、クエリに追加の条件を
加えて、より使いやすいデータを取得できます。

```sql title="Query" theme={null}
SELECT * FROM s3('s3://fsq-os-places-us-east-1/release/dt=2025-04-08/places/parquet/*')
   WHERE address IS NOT NULL AND postcode IS NOT NULL AND instagram IS NOT NULL LIMIT 1
```

```response theme={null}
Row 1:
──────
fsq_place_id:        59b2c754b54618784f259654
name:                Villa 722
latitude:            ᴺᵁᴸᴸ
longitude:           ᴺᵁᴸᴸ
address:             Gijzenveldstraat 75
locality:            Zutendaal
region:              Limburg
postcode:            3690
admin_region:        ᴺᵁᴸᴸ
post_town:           ᴺᵁᴸᴸ
po_box:              ᴺᵁᴸᴸ
country:             ᴺᵁᴸᴸ
date_created:        2017-09-08
date_refreshed:      2020-01-25
date_closed:         ᴺᵁᴸᴸ
tel:                 ᴺᵁᴸᴸ
website:             https://www.landal.be
email:               ᴺᵁᴸᴸ
facebook_id:         522698844570949 -- 522.70 trillion
instagram:           landalmooizutendaal
twitter:             landalzdl
fsq_category_ids:    ['56aa371be4b08b9a8d5734e1']
fsq_category_labels: ['Travel and Transportation > Lodging > Vacation Rental']
placemaker_url:      https://foursquare.com/placemakers/review-place/59b2c754b54618784f259654
geom:                ᴺᵁᴸᴸ
bbox:                (NULL,NULL,NULL,NULL)
```

次のクエリを実行し、`DESCRIBE` を使用してデータから自動的に推論されたスキーマを確認します：

```sql title="Query" theme={null}
DESCRIBE s3('s3://fsq-os-places-us-east-1/release/dt=2025-04-08/places/parquet/*')
```

```response title="Response" theme={null}
    ┌─name────────────────┬─type────────────────────────┬
 1. │ fsq_place_id        │ Nullable(String)            │
 2. │ name                │ Nullable(String)            │
 3. │ latitude            │ Nullable(Float64)           │
 4. │ longitude           │ Nullable(Float64)           │
 5. │ address             │ Nullable(String)            │
 6. │ locality            │ Nullable(String)            │
 7. │ region              │ Nullable(String)            │
 8. │ postcode            │ Nullable(String)            │
 9. │ admin_region        │ Nullable(String)            │
10. │ post_town           │ Nullable(String)            │
11. │ po_box              │ Nullable(String)            │
12. │ country             │ Nullable(String)            │
13. │ date_created        │ Nullable(String)            │
14. │ date_refreshed      │ Nullable(String)            │
15. │ date_closed         │ Nullable(String)            │
16. │ tel                 │ Nullable(String)            │
17. │ website             │ Nullable(String)            │
18. │ email               │ Nullable(String)            │
19. │ facebook_id         │ Nullable(Int64)             │
20. │ instagram           │ Nullable(String)            │
21. │ twitter             │ Nullable(String)            │
22. │ fsq_category_ids    │ Array(Nullable(String))     │
23. │ fsq_category_labels │ Array(Nullable(String))     │
24. │ placemaker_url      │ Nullable(String)            │
25. │ geom                │ Nullable(String)            │
26. │ bbox                │ Tuple(                     ↴│
    │                     │↳    xmin Nullable(Float64),↴│
    │                     │↳    ymin Nullable(Float64),↴│
    │                     │↳    xmax Nullable(Float64),↴│
    │                     │↳    ymax Nullable(Float64)) │
    └─────────────────────┴─────────────────────────────┘
```

<div id="loading-the-data">
  ## データを ClickHouse に読み込む
</div>

データをディスクに永続化する場合は、`clickhouse-server`
または ClickHouse Cloud を使用できます。

テーブルを作成するには、次のコマンドを実行します。

```sql title="Query" theme={null}
CREATE TABLE foursquare_mercator
(
    fsq_place_id String,
    name String,
    latitude Float64,
    longitude Float64,
    address String,
    locality String,
    region LowCardinality(String),
    postcode LowCardinality(String),
    admin_region LowCardinality(String),
    post_town LowCardinality(String),
    po_box LowCardinality(String),
    country LowCardinality(String),
    date_created Nullable(Date),
    date_refreshed Nullable(Date),
    date_closed Nullable(Date),
    tel String,
    website String,
    email String,
    facebook_id String,
    instagram String,
    twitter String,
    fsq_category_ids Array(String),
    fsq_category_labels Array(String),
    placemaker_url String,
    geom String,
    bbox Tuple(
        xmin Nullable(Float64),
        ymin Nullable(Float64),
        xmax Nullable(Float64),
        ymax Nullable(Float64)
    ),
    category LowCardinality(String) ALIAS fsq_category_labels[1],
    mercator_x UInt32 MATERIALIZED 0xFFFFFFFF * ((longitude + 180) / 360),
    mercator_y UInt32 MATERIALIZED 0xFFFFFFFF * ((1 / 2) - ((log(tan(((latitude + 90) / 360) * pi())) / 2) / pi())),
    INDEX idx_x mercator_x TYPE minmax,
    INDEX idx_y mercator_y TYPE minmax
)
ORDER BY mortonEncode(mercator_x, mercator_y)
```

[`LowCardinality`](/ja/reference/data-types/lowcardinality)
データ型が複数のカラムで使用されている点に注目してください。これにより、これらのデータ型の内部表現は
辞書エンコード形式に変わります。辞書エンコードされたデータを扱うことで、多くのアプリケーションで `SELECT` クエリの性能が
大幅に向上します。

さらに、2 つの `UInt32` `MATERIALIZED` カラム `mercator_x` と `mercator_y` が作成されます。
これらは、地図をタイルに分割しやすくするために、緯度・経度の座標を [Web Mercator projection](https://en.wikipedia.org/wiki/Web_Mercator_projection)
にマッピングするものです:

```sql theme={null}
mercator_x UInt32 MATERIALIZED 0xFFFFFFFF * ((longitude + 180) / 360),
mercator_y UInt32 MATERIALIZED 0xFFFFFFFF * ((1 / 2) - ((log(tan(((latitude + 90) / 360) * pi())) / 2) / pi())),
```

上で何が行われているのかを、各カラムごとに見ていきましょう。

**mercator\_x**

このカラムは、経度の値をメルカトル図法での X 座標に変換します。

* `longitude + 180` は、経度の範囲を \[-180, 180] から \[0, 360] にシフトします
* 360 で割ることで、これを 0 から 1 の間の値に正規化します
* `0xFFFFFFFF` (32 ビット符号なし整数の最大値を表す 16 進数) を掛けることで、この正規化された値を 32 ビット整数の全範囲にスケーリングします

**mercator\_y**

このカラムは、緯度の値をメルカトル図法での Y 座標に変換します。

* `latitude + 90` は、緯度の範囲を \[-90, 90] から \[0, 180] にシフトします
* 360 で割ってから pi() を掛けることで、三角関数で使うラジアンに変換します
* `log(tan(...))` の部分が、メルカトル図法の数式の中核です
* `0xFFFFFFFF` を掛けることで、32 ビット整数の全範囲にスケーリングします

`MATERIALIZED` を指定すると、ClickHouse はデータを `INSERT` するときにこれらの
カラムの値を計算します。これにより、元のデータスキーマに含まれていないこれらのカラムを
\`INSERTステートメントで指定する必要がなくなります。

このテーブルは `mortonEncode(mercator_x, mercator_y)` で順序付けされており、
これによって `mercator_x` と `mercator_y` の Z オーダー空間充填曲線が生成され、
地理空間クエリのクエリパフォーマンスが大幅に向上します。この Z オーダー曲線による並び順により、
データは空間的な近接性に基づいて物理的に配置されます。

```sql theme={null}
ORDER BY mortonEncode(mercator_x, mercator_y)
```

検索を高速化するために、`minmax` インデックスも 2 つ作成されます。

```sql theme={null}
INDEX idx_x mercator_x TYPE minmax,
INDEX idx_y mercator_y TYPE minmax
```

ご覧のとおり、ClickHouse にはリアルタイムの
マッピングアプリケーションに必要な機能がすべて揃っています！

データを読み込むには、次のクエリを実行します。

```sql theme={null}
INSERT INTO foursquare_mercator 
SELECT * FROM s3('s3://fsq-os-places-us-east-1/release/dt=2025-04-08/places/parquet/*')
```

<div id="data-visualization">
  ## データの可視化
</div>

このデータセットで何ができるのかを確認するには、[adsb.exposed](https://adsb.exposed/?dataset=Places\&zoom=5\&lat=52.3488\&lng=4.9219) をご覧ください。
adsb.exposed はもともと、共同創業者兼 CTO の Alexey Milovidov が、これより 1000 倍大規模な ADS-B (Automatic Dependent Surveillance-Broadcast)
の飛行データを可視化するために構築したものです。社内ハッカソンで、Alexey はこのツールに Foursquare のデータを追加しました。

以下では、特におすすめの可視化をいくつかご紹介します。

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-1d264819/oXXujd1EYkmtF-Zi/images/getting-started/example-datasets/visualization_1.png?fit=max&auto=format&n=oXXujd1EYkmtF-Zi&q=85&s=0a37f2edbd8e1543fed246a0b16670a5" size="md" alt="ヨーロッパのポイントオブインタレストの密度マップ" width="2251" height="1509" data-path="images/getting-started/example-datasets/visualization_1.png" />

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-1d264819/oXXujd1EYkmtF-Zi/images/getting-started/example-datasets/visualization_2.png?fit=max&auto=format&n=oXXujd1EYkmtF-Zi&q=85&s=4e9e829ba3f503c9acba378261330c69" size="md" alt="日本の日本酒バー" width="2381" height="1585" data-path="images/getting-started/example-datasets/visualization_2.png" />

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-1d264819/oXXujd1EYkmtF-Zi/images/getting-started/example-datasets/visualization_3.png?fit=max&auto=format&n=oXXujd1EYkmtF-Zi&q=85&s=df7a692fddd2af7f5625b5687e66be96" size="md" alt="ATM" width="2130" height="1565" data-path="images/getting-started/example-datasets/visualization_3.png" />

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-1d264819/oXXujd1EYkmtF-Zi/images/getting-started/example-datasets/visualization_4.png?fit=max&auto=format&n=oXXujd1EYkmtF-Zi&q=85&s=2bf76850818c8c22d3835e6f5bfeb0e6" size="md" alt="ポイントオブインタレストを国別に分類したヨーロッパ地図" width="633" height="583" data-path="images/getting-started/example-datasets/visualization_4.png" />
