-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
100 lines (85 loc) · 2.85 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { polygonContains } from 'https://cdn.skypack.dev/d3-polygon@3';
import * as ls from './localStorage.js';
const outputEl = document.querySelector('main');
navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
/**
* geoSuccess
* @description Fetch external or local data, find neighborhood, update DOM,
* set local data
* @param {Geolocation} position - Geolocation interface
*/
async function geoSuccess(position) {
const lat = position.coords.latitude;
const long = position.coords.longitude;
const alt = position.coords.altitude;
const point = [long, lat];
const dataAPI =
'https://services.arcgis.com/HfwHS0BxZBQ1E5DY/arcgis/rest/services/PoliticalBoundaries_mso/FeatureServer/0/query?outFields=*&where=1%3D1&f=geojson';
let hoods;
if (!ls.isAvailable() || !ls.get('NEIGHBORHOODSv1')) {
const response = await fetch(dataAPI);
hoods = await response.json();
} else {
hoods = JSON.parse(ls.get('NEIGHBORHOODSv1'));
}
const name = findHood(hoods, point);
updateDOM(name, lat, long, alt);
if (ls.isAvailable() && !ls.get('NEIGHBORHOODSv1')) {
ls.set('NEIGHBORHOODSv1', JSON.stringify(hoods));
}
}
function geoError(error) {
outputEl.textContent = error.message;
}
/**
* findHood
* @param {object} data - GeoJSON data
* @param {array} point - [long, lat]
* @returns {string|undefined} - the name of the neighborhood(s) or undefined
*/
function findHood(data, point) {
const hoods = data.features;
const hood = hoods.filter((feature) => {
// Two feature types: polygon, multipolygon
const polygon =
feature.geometry.type === 'Polygon'
? feature.geometry.coordinates[0]
: feature.geometry.coordinates[0][0];
return polygonContains(polygon, point);
});
if (hood.length === 1) {
return hood[0].properties['FeatureName'];
} else if (hood.length > 1) {
return hood.map((h) => h.properties['FeatureName']).join(' or ');
} else {
return undefined;
}
}
/**
* updateDOM
* @description Update DOM with neighborhood and position data
* @param {string|undefined} name - name of neighborhood(s)
* @param {string} lat - latitude
* @param {string} long - longitude
* @param {string} alt - altitude
*/
function updateDOM(name, lat, long, alt) {
const FT_IN_M = 3.28084;
const _lat = parseFloat(lat).toFixed(4);
const _long = parseFloat(long).toFixed(4);
const _alt = Math.round(parseFloat(alt).toFixed(2) * FT_IN_M);
let nameEl;
if (!name) {
nameEl = `<h2>It appears you aren't in Missoula 🙃🏔️🌲🐻</h2>`;
} else {
const moCitySearch = `https://www.ci.missoula.mt.us/Search?searchPhrase=${name}`;
nameEl = `<h2><a href="${moCitySearch}">${name}</a></h2>`;
}
const summary = `
<ul>
<li>Latitude: ${_lat}°</li>
<li>Longitude: ${_long}°</li>
<li>Altitude: ${_alt} ft</li>
</ul>`;
outputEl.innerHTML = nameEl + summary;
}