Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Migrate examples to TypeScript (#8759)
- Loading branch information
1 parent
254a4b9
commit 80ac105
Showing
66 changed files
with
1,315 additions
and
1,532 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2020", | ||
"jsx": "react", | ||
"moduleResolution": "node", | ||
"allowSyntheticDefaultImports": true | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* global fetch */ | ||
import React, {useEffect, useMemo, useState} from 'react'; | ||
import {createRoot} from 'react-dom/client'; | ||
import {Map} from 'react-map-gl//maplibre'; | ||
import DeckGL from '@deck.gl/react'; | ||
import {GeoJsonLayer, TextLayer} from '@deck.gl/layers'; | ||
import {CollisionFilterExtension, CollisionFilterExtensionProps} from '@deck.gl/extensions'; | ||
import {calculateLabels, Label} from './calculate-labels'; | ||
|
||
import type {Position, MapViewState} from '@deck.gl/core'; | ||
import type {FeatureCollection, Geometry} from 'geojson'; | ||
|
||
const DATA_URL = | ||
'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/collision-filter/ne_10_roads.json'; | ||
|
||
const INITIAL_VIEW_STATE: MapViewState = { | ||
longitude: -100, | ||
latitude: 24, | ||
zoom: 5, | ||
minZoom: 5, | ||
maxZoom: 12 | ||
}; | ||
|
||
type RoadProperties = { | ||
name: string; | ||
scalerank: number; | ||
}; | ||
|
||
export default function App({ | ||
mapStyle = 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json', | ||
sizeScale = 10, | ||
collisionEnabled = true, | ||
pointSpacing = 5 | ||
}: { | ||
mapStyle?: string; | ||
sizeScale?: number; | ||
collisionEnabled?: boolean; | ||
pointSpacing?: number | ||
}) { | ||
const [roads, setRoads] = useState<FeatureCollection<Geometry, RoadProperties>>(); | ||
|
||
useEffect(() => { | ||
fetch(DATA_URL) | ||
.then(resp => resp.json()) | ||
.then(setRoads); | ||
}, []); | ||
|
||
const roadLabels = useMemo(() => calculateLabels(roads, d => d.name !== null, pointSpacing), [roads, pointSpacing]); | ||
|
||
const layers = [ | ||
new GeoJsonLayer({ | ||
id: 'roads-outline', | ||
data: roads, | ||
getLineWidth: f => f.properties.scalerank + 2, | ||
lineWidthScale: 40, | ||
lineWidthMinPixels: 3, | ||
getLineColor: [0, 173, 230] | ||
}), | ||
new GeoJsonLayer({ | ||
id: 'roads', | ||
data: roads, | ||
getLineWidth: f => f.properties.scalerank, | ||
lineWidthScale: 40, | ||
lineWidthMinPixels: 1, | ||
parameters: {depthCompare: 'always'}, | ||
getLineColor: [255, 255, 255] | ||
}), | ||
new TextLayer<Label<RoadProperties>, CollisionFilterExtensionProps>({ | ||
id: 'labels', | ||
data: roadLabels, | ||
getColor: [0, 0, 0], | ||
getBackgroundColor: [255, 255, 255], | ||
getBorderColor: [0, 173, 230], | ||
getBorderWidth: 1, | ||
getPosition: d => d.position as Position, | ||
getText: d => d.parent.name, | ||
getSize: d => Math.max(d.parent.scalerank * 2, 10), | ||
getAngle: d => d.angle, | ||
billboard: false, | ||
background: true, | ||
backgroundPadding: [4, 1], | ||
characterSet: 'auto', | ||
fontFamily: 'monospace', | ||
|
||
// CollisionFilterExtension props | ||
collisionEnabled, | ||
getCollisionPriority: d => d.priority, | ||
collisionTestProps: {sizeScale}, | ||
extensions: [new CollisionFilterExtension()] | ||
}) | ||
]; | ||
|
||
return ( | ||
<DeckGL layers={layers} initialViewState={INITIAL_VIEW_STATE} controller={true}> | ||
<Map reuseMaps mapStyle={mapStyle} /> | ||
</DeckGL> | ||
); | ||
} | ||
|
||
export function renderToDOM(container: HTMLDivElement) { | ||
createRoot(container).render(<App />); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import {geomEach, along, rhumbBearing, lineDistance, lineString, booleanEqual} from '@turf/turf'; | ||
import type {FeatureCollection, Geometry, Feature, LineString} from 'geojson'; | ||
|
||
export type Label<FeatureProperties> = { | ||
position: number[]; | ||
priority: number; | ||
angle: number; | ||
parent: FeatureProperties; | ||
}; | ||
|
||
/* Utility to add rotated labels along lines and assign collision priorities */ | ||
export function calculateLabels<FeatureProperties>( | ||
geojson: FeatureCollection<Geometry, FeatureProperties> | undefined, | ||
filter: (properties: FeatureProperties) => boolean, | ||
pointSpacing: number | ||
): Label<FeatureProperties>[] { | ||
if (!geojson) return []; | ||
|
||
const result: Label<FeatureProperties>[] = []; | ||
|
||
function addLabelsAlongLineString(coordinates: LineString["coordinates"], properties: FeatureProperties) { | ||
// Add labels to minimize overlaps, pick odd values from each level | ||
// 1 <- depth 1 | ||
// 1 2 3 <- depth 2 | ||
// 1 2 3 4 5 6 7 <- depth 3 | ||
const feature = lineString(coordinates, properties); | ||
const lineLength = Math.floor(lineDistance(feature)); | ||
let delta = lineLength / 2; // Spacing between points at level | ||
let depth = 1; | ||
while (delta > pointSpacing) { | ||
for (let i = 1; i < 2 ** depth; i += 2) { | ||
const label = getLabelAtPoint(feature, lineLength, i * delta, 100 - depth); // Top levels have highest priority | ||
result.push(label); | ||
} | ||
depth++; | ||
delta /= 2; | ||
} | ||
} | ||
|
||
// @ts-ignore turf type FeatureCollection is not compatible with geojson type | ||
geomEach(geojson, (geometry: Geometry, i, properties: FeatureProperties) => { | ||
if (!filter(properties)) return; | ||
|
||
switch (geometry.type) { | ||
case 'LineString': | ||
addLabelsAlongLineString(geometry.coordinates, properties); | ||
break; | ||
|
||
case 'MultiLineString': | ||
for (const coordinates of geometry.coordinates) { | ||
addLabelsAlongLineString(coordinates, properties); | ||
} | ||
break; | ||
|
||
default: | ||
// ignore | ||
} | ||
}); | ||
|
||
return result; | ||
} | ||
|
||
function getLabelAtPoint<FeatureProperties>( | ||
line: Feature<LineString, FeatureProperties>, | ||
lineLength: number, | ||
dAlong: number, | ||
priority: number | ||
): Label<FeatureProperties> { | ||
const offset = dAlong + 1 < lineLength ? 1 : -1; | ||
const point = along(line, dAlong); | ||
const nextPoint = along(line, dAlong + offset); | ||
if (booleanEqual(point, nextPoint)) return; | ||
|
||
let angle = 90 - rhumbBearing(point, nextPoint); | ||
if (Math.abs(angle) > 90) angle += 180; | ||
|
||
return { | ||
position: point.geometry.coordinates, | ||
priority, | ||
angle, | ||
parent: line.properties | ||
}; | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.