Turf.jsを色々とためしてみた

![img](https://www.memo.dayjournal.dev/images/try-099_00.gif)
![img](https://www.memo.dayjournal.dev/images/try-099_00.png)

### Turf.jsを色々とためしてみました :tada:  

Turf.jsは、重心計算や距離計算等さまざまな位置情報データ処理が可能なオープンソースの地理空間解析ライブラリです。

今までに[dayjournal memo](https://memo.dayjournal.dev/tags/turf-js/)で、50種類以上の機能を試してきました。今回はその中でもおすすめの5つを紹介したいと思います！

<br>

詳細として下記について説明します。

- [事前準備](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99)
- [バッファ作成](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E3%83%90%E3%83%83%E3%83%95%E3%82%A1%E4%BD%9C%E6%88%90)
- [ポリゴン内に含まれるポイント抽出](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E3%83%9D%E3%83%AA%E3%82%B4%E3%83%B3%E5%86%85%E3%81%AB%E5%90%AB%E3%81%BE%E3%82%8C%E3%82%8B%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E6%8A%BD%E5%87%BA)
- [ポリゴンの重心取得](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E3%83%9D%E3%83%AA%E3%82%B4%E3%83%B3%E3%81%AE%E9%87%8D%E5%BF%83%E5%8F%96%E5%BE%97)
- [指定距離でライン上の位置取得](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E6%8C%87%E5%AE%9A%E8%B7%9D%E9%9B%A2%E3%81%A7%E3%83%A9%E3%82%A4%E3%83%B3%E4%B8%8A%E3%81%AE%E4%BD%8D%E7%BD%AE%E5%8F%96%E5%BE%97)
- [ポリゴンの自己交差取得](https://qiita.com/dayjournal/items/b89a8c650237738c975f#%E3%83%9D%E3%83%AA%E3%82%B4%E3%83%B3%E3%81%AE%E8%87%AA%E5%B7%B1%E4%BA%A4%E5%B7%AE%E5%8F%96%E5%BE%97)

## 事前準備

Turf.jsを手軽に始めるビルド環境を利用

https://github.com/dayjournal/turfjs-starter

<br>

## バッファ作成
ポイントからバッファを作成します。

![img](https://www.memo.dayjournal.dev/images/try-099_01.png)  

#### src/main.ts

```typescript
// ポイント取得
const point = turf.point([139.770, 35.676]);

// ポイント表示
map.addSource("FeaturesPoint", {
    type: "geojson",
    data: point
});
map.addLayer({
    id: "FeaturesPoint",
    type: "circle",
    source: "FeaturesPoint",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#1253A4",
        "circle-stroke-width": 5,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#1253A4",
        "circle-radius": 5,
        "circle-opacity": 0.5
    }
});

// バッファ計算
const buffered = turf.buffer(point, 10, {
    units: "kilometers"
});

// ポリゴン表示
map.addSource("PolygonSample", {
    type: "geojson",
    data: buffered
});
map.addLayer({
    id: "PolygonSample",
    type: "fill",
    source: "PolygonSample",
    layout: {},
    paint: {
        "fill-color": "#58BE89",
        "fill-opacity": 0.5
    }
});
map.addLayer({
    id: "PolygonLineSample",
    type: "line",
    source: "PolygonSample",
    layout: {
        "line-join": "round",
        "line-cap": "round"
    },
    paint: {
        "line-color": "#58BE89",
        "line-width": 5,
        "line-opacity": 0.8
    }
});
```

https://www.memo.dayjournal.dev/memo/turf-js-024

<br>

## ポリゴン内に含まれるポイント抽出
ポリゴン内に含まれるポイントを抽出します。

![img](https://www.memo.dayjournal.dev/images/try-099_02.png)  

#### src/main.ts

```typescript
// ランダムポイント取得
const points = turf.randomPoint(30,
    {
        bbox: [139.7533, 35.6713, 139.7808, 35.6901]
    }
);

// ポイント表示
map.addSource("RandomPoint", {
    type: "geojson",
    data: points
});
map.addLayer({
    id: "RandomPoint",
    type: "circle",
    source: "RandomPoint",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#8DCF3F",
        "circle-stroke-width": 10,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#8DCF3F",
        "circle-radius": 10,
        "circle-opacity": 0.5
    }
});


// ポリゴン取得
const polygon = turf.polygon([[
    [139.7661, 35.6759],
    [139.7718, 35.6741],
    [139.7722, 35.6745],
    [139.7786, 35.6837],
    [139.7734, 35.6843],
    [139.7709, 35.6846],
    [139.7687, 35.6799],
    [139.7661, 35.6759]
]]);

// ポリゴン表示
map.addSource("PolygonSample", {
    type: "geojson",
    data: polygon
});
map.addLayer({
    id: "PolygonSample",
    type: "fill",
    source: "PolygonSample",
    layout: {},
    paint: {
        "fill-color": "#FFD464",
        "fill-opacity": 0.5
    }
});
map.addLayer({
    id: "PolygonLineSample",
    type: "line",
    source: "PolygonSample",
    layout: {
        "line-join": "round",
        "line-cap": "round"
    },
    paint: {
        "line-color": "#FFD464",
        "line-width": 5,
        "line-opacity": 0.8
    }
});

// ポリゴン内にあるポイント取得
const ptsWithin = turf.pointsWithinPolygon(points, polygon);

// ポイント表示
map.addSource("Points", {
    type: "geojson",
    data: ptsWithin
});
map.addLayer({
    id: "Points",
    type: "circle",
    source: "Points",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#1253A4",
        "circle-stroke-width": 5,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#1253A4",
        "circle-radius": 5,
        "circle-opacity": 0.5
    }
});
```

https://www.memo.dayjournal.dev/memo/turf-js-044

<br>

## ポリゴンの重心取得
ポリゴンの重心を取得します。

![img](https://www.memo.dayjournal.dev/images/try-099_03.png)  

#### src/main.ts

```typescript
// ポリゴンを取得
const polygon = turf.polygon([[
    [139.7661, 35.6759],
    [139.7718, 35.6741],
    [139.7722, 35.6745],
    [139.7786, 35.6837],
    [139.7734, 35.6843],
    [139.7709, 35.6846],
    [139.7687, 35.6799],
    [139.7661, 35.6759]
]]);

// ポリゴン表示
map.addSource("PolygonSample", {
    type: "geojson",
    data: polygon
});
map.addLayer({
    id: "PolygonSample",
    type: "fill",
    source: "PolygonSample",
    layout: {},
    paint: {
        "fill-color": "#58BE89",
        "fill-opacity": 0.5
    }
});
map.addLayer({
    id: "PolygonLineSample",
    type: "line",
    source: "PolygonSample",
    layout: {
        "line-join": "round",
        "line-cap": "round"
    },
    paint: {
        "line-color": "#58BE89",
        "line-width": 5,
        "line-opacity": 0.8
    }
});

// ポリゴンの重心取得
const centroid = turf.centroid(polygon);

// ポイント表示
map.addSource("FeaturesPoint", {
    type: "geojson",
    data: centroid
});
map.addLayer({
    id: "FeaturesPoint",
    type: "circle",
    source: "FeaturesPoint",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#1253A4",
        "circle-stroke-width": 5,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#1253A4",
        "circle-radius": 8,
        "circle-opacity": 0.5
    }
});
```

https://www.memo.dayjournal.dev/memo/turf-js-022

<br>

## 指定距離でライン上の位置取得
指定距離でライン上の位置を取得します。

![img](https://www.memo.dayjournal.dev/images/try-099_04.png)  

#### src/main.ts

```typescript
// ライン取得
const line = turf.lineString([
    [139.7506, 35.6611],
    [139.7648, 35.6736],
    [139.7689, 35.6854]
]);

// ライン表示
map.addSource("LineSample", {
    type: "geojson",
    data: line
});
map.addLayer({
    id: "LineSample",
    type: "line",
    source: "LineSample",
    layout: {
        "line-join": "round",
        "line-cap": "round"
    },
    paint: {
        "line-color": "#1253A4",
        "line-width": 5,
        "line-opacity": 0.6
    }
});


// ライン上の指定距離でポイント取得
const point = turf.along(line, 2, {
    units: "kilometers"
});

// ポイント表示
map.addSource("PointSample", {
    type: "geojson",
    data: point
});
map.addLayer({
    id: "PointSample",
    type: "circle",
    source: "PointSample",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#8DCF3F",
        "circle-stroke-width": 10,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#8DCF3F",
        "circle-radius": 10,
        "circle-opacity": 0.5
    }
});
```

https://www.memo.dayjournal.dev/memo/turf-js-008

<br>

## ポリゴンの自己交差取得
ポリゴンの自己交差を取得します。

![img](https://www.memo.dayjournal.dev/images/try-099_05.png)  

#### src/main.ts

```typescript
// ポリゴンを取得
const polygon = turf.polygon([[
    [139.76398944854733, 35.68560526180893],
    [139.75956916809082, 35.681003987351055],
    [139.7629165649414, 35.67378781807109],
    [139.76879596710205, 35.67570522138987],
    [139.7691822052002, 35.6794004505696],
    [139.75961208343506, 35.67549605235727],
    [139.75948333740234, 35.67786660262532],
    [139.76265907287595, 35.680446239082066],
    [139.7603416442871, 35.68504754570482],
    [139.7706413269043, 35.68421096423828],
    [139.77059841156006, 35.68581440434281],
    [139.76398944854733, 35.68560526180893]
]]);

// ポリゴン表示
map.addSource("PolygonSample", {
    type: "geojson",
    data: polygon
});
map.addLayer({
    id: "PolygonSample",
    type: "fill",
    source: "PolygonSample",
    layout: {},
    paint: {
        "fill-color": "#FFD464",
        "fill-opacity": 0.5
    }
});
map.addLayer({
    id: "PolygonLineSample",
    type: "line",
    source: "PolygonSample",
    layout: {
        "line-join": "round",
        "line-cap": "round"
    },
    paint: {
        "line-color": "#FFD464",
        "line-width": 5,
        "line-opacity": 0.8
    }
});

// ポリゴンの自己交差取得
const point = turf.kinks(polygon);

// ポイント表示
map.addSource("FeaturesPoint", {
    type: "geojson",
    data: point
});
map.addLayer({
    id: "FeaturesPoint",
    type: "circle",
    source: "FeaturesPoint",
    layout: {},
    paint: {
        "circle-pitch-alignment": "map",
        "circle-stroke-color": "#1253A4",
        "circle-stroke-width": 5,
        "circle-stroke-opacity": 0.8,
        "circle-color": "#1253A4",
        "circle-radius": 5,
        "circle-opacity": 0.5
    }
});
```
https://www.memo.dayjournal.dev/memo/turf-js-039

<br>
<br>
<br>

Turf.jsのプロセッシングについて、他にも記事を書いています。よろしければぜひ :bow:
<a href="https://memo.dayjournal.dev/tags/turf-js/" target="_blank">tags - Turf.js</a>

<br>
<br>

<a href="https://dayjournal.booth.pm" target="_blank"><img src="https://day-journal.com/memo/images/etc/book.png" alt="book"></a>