Skip to content

Commit d783b6c

Browse files
committed
show results on a map
1 parent 4e98c0d commit d783b6c

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

src/Results/MapLink.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type { FunctionComponent } from 'preact';
2+
import { useCallback } from 'preact/hooks';
3+
import type {
4+
Feature,
5+
FeatureCollection,
6+
GeoJsonProperties,
7+
Geometry,
8+
Point,
9+
} from 'geojson';
10+
import Icon from '../Icon';
11+
import { selectGameConfig } from '../gameConfig';
12+
import { useAppSelector } from '../store';
13+
14+
interface Props {
15+
results: FeatureCollection<Point>;
16+
}
17+
18+
const makeRed = <T extends Geometry, P extends GeoJsonProperties>(
19+
f: Feature<T, P>
20+
) => ({
21+
...f,
22+
properties: { ...f.properties, title: 'Target', 'marker-color': '#f00' },
23+
});
24+
25+
const makePlacements = <P extends GeoJsonProperties>(
26+
f: Feature<Point, P>,
27+
i: number
28+
): Feature<Point, P> => {
29+
if (i >= 9) {
30+
return f;
31+
} else {
32+
return {
33+
...f,
34+
properties: { ...f.properties, 'marker-symbol': i + 1 },
35+
};
36+
}
37+
};
38+
39+
const MapLink: FunctionComponent<Props> = ({ results }) => {
40+
const gameConfig = useAppSelector(selectGameConfig);
41+
const target = gameConfig?.target;
42+
43+
const onClick = useCallback(() => {
44+
const a = document.createElement('a');
45+
let targets: Feature[];
46+
if (!target) {
47+
targets = [];
48+
} else if (target.type === 'FeatureCollection') {
49+
targets = target.features;
50+
} else {
51+
targets = [target];
52+
}
53+
const resultsWithTarget = {
54+
...results,
55+
features: [
56+
...targets.map(makeRed),
57+
...results.features.slice(0, 100).map(makePlacements),
58+
],
59+
};
60+
const url =
61+
'http://geojson.io/#data=data:application/json,' +
62+
encodeURIComponent(JSON.stringify(resultsWithTarget));
63+
window.open(url, '_blank');
64+
}, [results, target]);
65+
66+
return <Icon name="map-location-dot" onClick={onClick} label="View Map" />;
67+
};
68+
69+
export default MapLink;

src/Results/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { decorate } from '../computation';
33
import { selectExtraGc, selectGameConfig } from '../gameConfig';
44
import { createAppSelector, useAppSelector } from '../store';
55
import Grid from './Grid';
6+
import MapLink from './MapLink';
67

78
const selectResults = createAppSelector(
89
[selectGameConfig, (state) => state.data.photos],
@@ -21,7 +22,9 @@ const Results: FunctionComponent = () => {
2122
if (results && results.features.length > 0) {
2223
return (
2324
<>
24-
<h2>Results</h2>
25+
<h2>
26+
Results <MapLink results={results} />
27+
</h2>
2528
<Grid results={results} extraGc={extraGc} />
2629
</>
2730
);

src/index.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</head>
99
<body>
1010
<svg xmlns="http://www.w3.org/2000/svg" id="sprites">
11-
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
11+
<!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
1212
<defs>
1313
<g id="copy">
1414
<svg viewBox="0 0 448 512">
@@ -31,6 +31,13 @@
3131
/>
3232
</svg>
3333
</g>
34+
<g id="map-location-dot">
35+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512">
36+
<path
37+
d="M576 48c0-11.1-5.7-21.4-15.2-27.2s-21.2-6.4-31.1-1.4L413.5 77.5 234.1 17.6c-8.1-2.7-16.8-2.1-24.4 1.7l-128 64C70.8 88.8 64 99.9 64 112l0 352c0 11.1 5.7 21.4 15.2 27.2s21.2 6.4 31.1 1.4l116.1-58.1 173.3 57.8c-4.3-6.4-8.5-13.1-12.6-19.9-11-18.3-21.9-39.3-30-61.8l-101.2-33.7 0-284.5 128 42.7 0 99.3c31-35.8 77-58.4 128-58.4 22.6 0 44.2 4.4 64 12.5L576 48zM512 224c-66.3 0-120 52.8-120 117.9 0 68.9 64.1 150.4 98.6 189.3 11.6 13 31.3 13 42.9 0 34.5-38.9 98.6-120.4 98.6-189.3 0-65.1-53.7-117.9-120-117.9zM472 344a40 40 0 1 1 80 0 40 40 0 1 1 -80 0z"
38+
/>
39+
</svg>
40+
</g>
3441
</defs>
3542
</svg>
3643
<div id="app"></div>

0 commit comments

Comments
 (0)