diff --git a/components/PrintableMap.vue b/components/PrintableMap.vue index 0fed5a0b..e6384c0c 100644 --- a/components/PrintableMap.vue +++ b/components/PrintableMap.vue @@ -142,6 +142,7 @@ div import "maplibre-gl/dist/maplibre-gl.css"; import "simplebar/dist/simplebar.min.css"; import MapLibre from "maplibre-gl"; +import Supercluster from 'supercluster'; import { getNowYMD } from "~/lib/displayHelper"; const crc16 = require("js-crc").crc16; @@ -193,14 +194,38 @@ export default { return newConfig; }, inBoundsMarkers() { - const inBoundsMarkers = this.layers - .filter(l => l.source.show && this.checkedArea.includes(l.source.title)) + if (!this.bounds) return []; + + // SuperClusterに食わせるためにGeoJSON-Featureの配列を作成 + const features = this.layers + .filter(l => l.source.show && this.checkedArea.includes(l.source.title)) // 表示中のソースのみ .map(l => l.markers).flat() - .filter((marker) => { - if (!this.bounds) return true; - return helper.inBounds(marker.feature.geometry.coordinates, this.bounds); + .filter((marker) => helper.inBounds(marker.feature.geometry.coordinates, this.bounds)) // 表示範囲内のマーカーのみ + .map(m => ({...m.feature, properties: {...m.feature.properties, category: m.category}})); // categoryを保存 + + // SuperClusterでクラスタリング + const index = new Supercluster({ + radius: 20, // px: クラスタリングする範囲 + maxZoom: 9 // クラスタリングする最大のズームレベル + }); + index.load(features); + const clustered = index.getClusters([-180, -85, 180, 85], Math.floor(this.map.map.getZoom())); + + // システムに準拠した構造に変換: Array<{feature: GeoJSON-Feature, category: カテゴリ名}> + const markers = clustered + .map((feature) => { + let _feature = feature; + if (feature.properties.cluster) { + _feature = index.getLeaves(feature.properties.cluster_id, 1)[0]; + } + const marker = { + feature: _feature, + category: _feature.properties.category, + }; + return marker; }); - return inBoundsMarkers; + + return markers; }, displayMarkersGroupByCategory() { const resultGroupBy = this.inBoundsMarkers.reduce((groups, current) => { diff --git a/package.json b/package.json index 93858c24..112abca1 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "nuxt": "^2.14.7", "nuxt-i18n": "^6.20.4", "simplebar-vue": "^1.6.0", + "supercluster": "7.1.5", "ts-node": "^8.10.2", "viewport-units-buggyfill": "^0.6.2", "vue": "^2.7.0", @@ -93,4 +94,4 @@ "ts-loader": "^6.2.2", "typescript": "^5.3.3" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 7eb2a5cb..ddc5768d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11908,7 +11908,7 @@ stylehacks@^6.0.1: browserslist "^4.21.4" postcss-selector-parser "^6.0.4" -supercluster@^7.1.0: +supercluster@7.1.5, supercluster@^7.1.0: version "7.1.5" resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.5.tgz#65a6ce4a037a972767740614c19051b64b8be5a3" integrity sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==