Skip to content

Commit 8b69b8f

Browse files
committed
2 parents f13a58f + 388b83f commit 8b69b8f

File tree

5 files changed

+156
-6
lines changed

5 files changed

+156
-6
lines changed

AllPointsWithUnits.geojson

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

AllPointsWithUnits.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

homesteadmap.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474

7575
map.addSource('StoweAllResi', {
7676
type: 'geojson',
77-
data: 'StoweAllResi2.geojson'
77+
data: 'AllPointsWithUnits.geojson'
7878
});
7979

8080
map.addSource('STR', {
@@ -89,7 +89,7 @@
8989

9090
map.addSource('resi', {
9191
type: 'geojson',
92-
data: 'resipoints.geojson'
92+
data: 'AllPointsWithUnits.geojson'
9393
});
9494

9595
map.addLayer({
@@ -125,8 +125,6 @@
125125
});
126126

127127

128-
map.setFilter('STR-homestead-or-no', ['==', ['get', 'STR__5__bookings_'], 'Yes']);
129-
130128
});
131129

132130

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575

7676
map.addSource('StoweAllResi', {
7777
type: 'geojson',
78-
data: 'StoweAllResi2.geojson'
78+
data: 'AllPointsWithUnits.geojson'
7979
});
8080

8181
map.addSource('STR', {
@@ -90,7 +90,7 @@
9090

9191
map.addSource('resi', {
9292
type: 'geojson',
93-
data: 'resipoints.geojson'
93+
data: 'AllPointsWithUnits.geojson'
9494
});
9595

9696
map.addLayer({

homesteadmap_condohalo.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<title>Condo halo on hover</title>
7+
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
8+
<link href="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.css" rel="stylesheet">
9+
<script src="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.js"></script>
10+
<style>
11+
body {
12+
margin: 0;
13+
padding: 0;
14+
}
15+
16+
#map {
17+
position: absolute;
18+
top: 0;
19+
bottom: 0;
20+
width: 100%;
21+
}
22+
</style>
23+
</head>
24+
25+
<body>
26+
<div id="map"></div>
27+
<script>
28+
mapboxgl.accessToken = 'pk.eyJ1Ijoic2FyYWJyZW50IiwiYSI6ImNtMHpsb2Q4NTAwemoybHExbnB6eHVvZ2kifQ.nH0hUSv3IGzX6MkYB_cSmA';
29+
const map = new mapboxgl.Map({
30+
container: 'map',
31+
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
32+
style: 'mapbox://styles/mapbox/satellite-streets-v12',
33+
zoom: 11,
34+
center: [-72.688122, 44.467397],
35+
projection: 'globe'
36+
});
37+
38+
let originalGeoJSON;
39+
40+
41+
42+
map.on('load', () => {
43+
map.addSource('boundary', {
44+
type: 'geojson',
45+
data: 'Boundary.geojson'
46+
});
47+
48+
map.addLayer({
49+
id: 'boundary',
50+
type: 'line',
51+
source: 'boundary',
52+
paint: {
53+
'line-color': 'white'
54+
}
55+
});
56+
57+
fetch('AllPointsWithUnits.geojson')
58+
.then(res => res.json())
59+
.then(data => {
60+
// Store original data for restoration later
61+
// 🔧 Step 1: Count duplicate coordinates
62+
const coordMap = {};
63+
data.features.forEach(f => {
64+
const key = f.geometry.coordinates.join(',');
65+
coordMap[key] = (coordMap[key] || 0) + 1;
66+
});
67+
68+
// 🔧 Step 2: Tag features with hasDuplicates
69+
data.features.forEach(f => {
70+
const key = f.geometry.coordinates.join(',');
71+
f.properties.hasDuplicates = coordMap[key] > 1;
72+
});
73+
74+
// 🔧 Step 3: Now clone with tags intact
75+
originalGeoJSON = JSON.parse(JSON.stringify(data));
76+
77+
map.addSource('resi2', {
78+
type: 'geojson',
79+
data: data
80+
});
81+
82+
83+
map.addLayer({
84+
id: 'ResiAll',
85+
type: 'circle',
86+
source: 'resi2',
87+
paint: {
88+
'circle-color': [
89+
'match',
90+
['get', 'homestead'],
91+
'yes', '#1E88E5',
92+
'no', '#FFC107',
93+
'#000000'
94+
],
95+
'circle-radius': 6,
96+
'circle-stroke-color': '#000',
97+
'circle-stroke-width': 1
98+
}
99+
});
100+
101+
map.addLayer({
102+
id: 'ResiAll-halo',
103+
type: 'circle',
104+
source: 'resi2',
105+
filter: ['==', ['get', 'hasDuplicates'], true],
106+
paint: {
107+
'circle-color': 'white',
108+
'circle-radius': 16,
109+
'circle-blur': 0.8,
110+
'circle-opacity': 1
111+
}
112+
}, 'ResiAll');
113+
114+
map.on('mousemove', 'ResiAll', (e) => {
115+
const features = map.queryRenderedFeatures(e.point, { layers: ['ResiAll'] });
116+
117+
if (features.length <= 1) {
118+
map.getSource('resi2').setData(originalGeoJSON);
119+
return;
120+
}
121+
122+
const fanned = JSON.parse(JSON.stringify(originalGeoJSON));
123+
const centerCoord = features[0].geometry.coordinates;
124+
const angleStep = (2 * Math.PI) / features.length;
125+
const radius = 0.0001; // ~11 meters offset
126+
127+
features.forEach((f, i) => {
128+
const idx = fanned.features.findIndex(orig => orig.id === f.id);
129+
if (idx === -1) return;
130+
const angle = i * angleStep;
131+
const dx = radius * Math.cos(angle);
132+
const dy = radius * Math.sin(angle);
133+
fanned.features[idx].geometry.coordinates = [
134+
centerCoord[0] + (dx*1.5),
135+
centerCoord[1] + (dy*1)
136+
];
137+
});
138+
139+
map.getSource('resi2').setData(fanned);
140+
});
141+
142+
map.on('mouseleave', 'ResiAll', () => {
143+
map.getSource('resi2').setData(originalGeoJSON);
144+
});
145+
});
146+
});
147+
</script>
148+
</body>
149+
150+
</html>

0 commit comments

Comments
 (0)