mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-19 10:09:29 -07:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c38260725 | ||
|
|
94fafc247a | ||
|
|
703d64f6b2 | ||
|
|
e5a18ea073 |
File diff suppressed because it is too large
Load Diff
17236
datagenerators/output/stations.json
Normal file
17236
datagenerators/output/stations.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,43 +4,61 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('./https');
|
||||
const states = require('./stations-states');
|
||||
const chunk = require('./chunk');
|
||||
|
||||
// immediately invoked function so we can access async/await
|
||||
const start = async () => {
|
||||
// load the list of states
|
||||
const states = ['AK', 'NC', 'VA', 'TX', 'GA', 'PR'];
|
||||
// const states = require('./stations-states.js');
|
||||
// chunk the list of states
|
||||
const chunkStates = chunk(states, 5);
|
||||
|
||||
// store output
|
||||
const output = {};
|
||||
// loop through states
|
||||
await Promise.all(states.map(async (state) => {
|
||||
try {
|
||||
// get list and parse the JSON
|
||||
const stationsRaw = await https(`https://api.weather.gov/stations?state=${state}`);
|
||||
const stationsAll = JSON.parse(stationsRaw).features;
|
||||
// filter stations for 4 letter identifiers
|
||||
const stations = stationsAll.filter((station) => station.properties.stationIdentifier.match(/^[A-Z]{4}$/));
|
||||
// add each resulting station to the output
|
||||
stations.forEach((station) => {
|
||||
const id = station.properties.stationIdentifier;
|
||||
if (output[id]) {
|
||||
console.log(`Duplicate station: ${state}-${id}`);
|
||||
return;
|
||||
|
||||
// process all chunks
|
||||
for (let i = 0; i < chunkStates.length; i += 1) {
|
||||
const stateChunk = chunkStates[i];
|
||||
// loop through states
|
||||
|
||||
stateChunk.forEach(async (state) => {
|
||||
try {
|
||||
let stations;
|
||||
let next = `https://api.weather.gov/stations?state=${state}`;
|
||||
do {
|
||||
// get list and parse the JSON
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const stationsRaw = await https(next);
|
||||
stations = JSON.parse(stationsRaw);
|
||||
// filter stations for 4 letter identifiers
|
||||
const stationsFiltered = stations.features.filter((station) => station.properties.stationIdentifier.match(/^[A-Z]{4}$/));
|
||||
// add each resulting station to the output
|
||||
stationsFiltered.forEach((station) => {
|
||||
const id = station.properties.stationIdentifier;
|
||||
if (output[id]) {
|
||||
console.log(`Duplicate station: ${state}-${id}`);
|
||||
return;
|
||||
}
|
||||
output[id] = {
|
||||
id,
|
||||
city: station.properties.name,
|
||||
state,
|
||||
lat: station.geometry.coordinates[1],
|
||||
lon: station.geometry.coordinates[0],
|
||||
};
|
||||
});
|
||||
next = stations?.pagination?.next;
|
||||
// write the output
|
||||
fs.writeFileSync(path.join(__dirname, 'output/stations.json'), JSON.stringify(output, null, 2));
|
||||
}
|
||||
output[id] = {
|
||||
id,
|
||||
city: station.properties.name,
|
||||
state,
|
||||
lat: station.geometry.coordinates[1],
|
||||
lon: station.geometry.coordinates[0],
|
||||
};
|
||||
});
|
||||
console.log(`Complete: ${state}`);
|
||||
} catch (e) {
|
||||
console.error(`Unable to get state: ${state}`);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
while (next && stations.features.length > 0);
|
||||
console.log(`Complete: ${state}`);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(`Unable to get state: ${state}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// write the output
|
||||
fs.writeFileSync(path.join(__dirname, 'output/stations.js'), JSON.stringify(output, null, 2));
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ws4kp",
|
||||
"version": "5.5.2",
|
||||
"version": "5.6.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ws4kp",
|
||||
"version": "5.5.2",
|
||||
"version": "5.6.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eslint": "^8.21.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ws4kp",
|
||||
"version": "5.5.2",
|
||||
"version": "5.6.0",
|
||||
"description": "Welcome to the WeatherStar 4000+ project page!",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,12 +3,13 @@ import noSleep from './modules/utils/nosleep.mjs';
|
||||
import {
|
||||
message as navMessage, isPlaying, resize, resetStatuses, latLonReceived, stopAutoRefreshTimer, registerRefreshData,
|
||||
} from './modules/navigation.mjs';
|
||||
import { round2 } from './modules/utils/units.mjs';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
init();
|
||||
});
|
||||
|
||||
let FullScreenOverride = false;
|
||||
let fullScreenOverride = false;
|
||||
|
||||
const categories = [
|
||||
'Land Features',
|
||||
@@ -27,7 +28,7 @@ const init = () => {
|
||||
e.target.select();
|
||||
});
|
||||
|
||||
registerRefreshData(LoadTwcData);
|
||||
registerRefreshData(loadData);
|
||||
|
||||
document.getElementById('NavigateMenu').addEventListener('click', btnNavigateMenuClick);
|
||||
document.getElementById('NavigateRefresh').addEventListener('click', btnNavigateRefreshClick);
|
||||
@@ -38,11 +39,11 @@ const init = () => {
|
||||
document.getElementById('btnGetGps').addEventListener('click', btnGetGpsClick);
|
||||
|
||||
document.getElementById('divTwc').addEventListener('click', () => {
|
||||
if (document.fullscreenElement) UpdateFullScreenNavigate();
|
||||
if (document.fullscreenElement) updateFullScreenNavigate();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', documentKeydown);
|
||||
document.addEventListener('touchmove', (e) => { if (FullScreenOverride) e.preventDefault(); });
|
||||
document.addEventListener('touchmove', (e) => { if (fullScreenOverride) e.preventDefault(); });
|
||||
|
||||
$('#frmGetLatLng #txtAddress').devbridgeAutocomplete({
|
||||
serviceUrl: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest',
|
||||
@@ -56,7 +57,7 @@ const init = () => {
|
||||
},
|
||||
dataType: 'json',
|
||||
transformResult: (response) => ({
|
||||
suggestions: $.map(response.suggestions, (i) => ({
|
||||
suggestions: response.suggestions.map((i) => ({
|
||||
value: i.text,
|
||||
data: i.magicKey,
|
||||
})),
|
||||
@@ -68,23 +69,23 @@ const init = () => {
|
||||
width: 490,
|
||||
});
|
||||
|
||||
const ac = $('#frmGetLatLng #txtAddress').devbridgeAutocomplete();
|
||||
$('#frmGetLatLng').on('submit', () => {
|
||||
if (ac.suggestions[0]) $(ac.suggestionsContainer.children[0]).click();
|
||||
const ac = $('#frmGetLatLng #txtAddress').devbridgeAutocomplete();
|
||||
if (ac.suggestions[0]) $(ac.suggestionsContainer.children[0]).trigger('click');
|
||||
return false;
|
||||
});
|
||||
|
||||
// Auto load the previous query
|
||||
const TwcQuery = localStorage.getItem('TwcQuery');
|
||||
const TwcLatLong = localStorage.getItem('TwcLatLon');
|
||||
if (TwcQuery && TwcLatLong) {
|
||||
const query = localStorage.getItem('latLonQuery');
|
||||
const latLon = localStorage.getItem('latLonLon');
|
||||
if (query && latLon) {
|
||||
const txtAddress = document.getElementById('txtAddress');
|
||||
txtAddress.value = TwcQuery;
|
||||
LoadTwcData(JSON.parse(TwcLatLong));
|
||||
txtAddress.value = query;
|
||||
loadData(JSON.parse(latLon));
|
||||
}
|
||||
|
||||
const TwcPlay = localStorage.getItem('TwcPlay');
|
||||
if (TwcPlay === null || TwcPlay === 'true') postMessage('navButton', 'play');
|
||||
const twcPlay = localStorage.getItem('play');
|
||||
if (twcPlay === null || twcPlay === 'true') postMessage('navButton', 'play');
|
||||
|
||||
document.getElementById('btnClearQuery').addEventListener('click', () => {
|
||||
document.getElementById('spanCity').innerHTML = '';
|
||||
@@ -93,19 +94,14 @@ const init = () => {
|
||||
document.getElementById('spanRadarId').innerHTML = '';
|
||||
document.getElementById('spanZoneId').innerHTML = '';
|
||||
|
||||
localStorage.removeItem('TwcScrollText');
|
||||
localStorage.removeItem('TwcScrollTextChecked');
|
||||
|
||||
document.getElementById('chkAutoRefresh').checked = true;
|
||||
localStorage.removeItem('TwcAutoRefresh');
|
||||
localStorage.removeItem('autoRefresh');
|
||||
|
||||
document.getElementById('radEnglish').checked = true;
|
||||
|
||||
localStorage.removeItem('TwcPlay');
|
||||
localStorage.removeItem('play');
|
||||
postMessage('navButton', 'play');
|
||||
|
||||
localStorage.removeItem('TwcQuery');
|
||||
localStorage.removeItem('TwcLatLon');
|
||||
localStorage.removeItem('latLonQuery');
|
||||
localStorage.removeItem('latLonLon');
|
||||
});
|
||||
|
||||
// swipe functionality
|
||||
@@ -134,20 +130,20 @@ const autocompleteOnSelect = async (suggestion, elem) => {
|
||||
};
|
||||
|
||||
const doRedirectToGeometry = (geom) => {
|
||||
const latLon = { lat: Math.round2(geom.y, 4), lon: Math.round2(geom.x, 4) };
|
||||
const latLon = { lat: round2(geom.y, 4), lon: round2(geom.x, 4) };
|
||||
// Save the query
|
||||
localStorage.setItem('TwcQuery', document.getElementById('txtAddress').value);
|
||||
localStorage.setItem('TwcLatLon', JSON.stringify(latLon));
|
||||
localStorage.setItem('latLonQuery', document.getElementById('txtAddress').value);
|
||||
localStorage.setItem('latLonLon', JSON.stringify(latLon));
|
||||
|
||||
// get the data
|
||||
LoadTwcData(latLon);
|
||||
loadData(latLon);
|
||||
};
|
||||
|
||||
const btnFullScreenClick = () => {
|
||||
if (!document.fullscreenElement) {
|
||||
EnterFullScreen();
|
||||
enterFullScreen();
|
||||
} else {
|
||||
ExitFullscreen();
|
||||
exitFullscreen();
|
||||
}
|
||||
|
||||
if (isPlaying()) {
|
||||
@@ -156,12 +152,12 @@ const btnFullScreenClick = () => {
|
||||
noSleep(false);
|
||||
}
|
||||
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const EnterFullScreen = () => {
|
||||
const enterFullScreen = () => {
|
||||
const element = document.getElementById('divTwc');
|
||||
|
||||
// Supports most browsers and their versions.
|
||||
@@ -174,10 +170,10 @@ const EnterFullScreen = () => {
|
||||
} else {
|
||||
// iOS doesn't support FullScreen API.
|
||||
window.scrollTo(0, 0);
|
||||
FullScreenOverride = true;
|
||||
fullScreenOverride = true;
|
||||
}
|
||||
resize();
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
// change hover text and image
|
||||
const img = document.getElementById('ToggleFullScreen');
|
||||
@@ -185,11 +181,11 @@ const EnterFullScreen = () => {
|
||||
img.title = 'Exit fullscreen';
|
||||
};
|
||||
|
||||
const ExitFullscreen = () => {
|
||||
const exitFullscreen = () => {
|
||||
// exit full-screen
|
||||
|
||||
if (FullScreenOverride) {
|
||||
FullScreenOverride = false;
|
||||
if (fullScreenOverride) {
|
||||
fullScreenOverride = false;
|
||||
}
|
||||
|
||||
if (document.exitFullscreen) {
|
||||
@@ -211,15 +207,15 @@ const ExitFullscreen = () => {
|
||||
|
||||
const btnNavigateMenuClick = () => {
|
||||
postMessage('navButton', 'menu');
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
return false;
|
||||
};
|
||||
|
||||
const LoadTwcData = (_latLon) => {
|
||||
const loadData = (_latLon) => {
|
||||
// if latlon is provided store it locally
|
||||
if (_latLon) LoadTwcData.latLon = _latLon;
|
||||
if (_latLon) loadData.latLon = _latLon;
|
||||
// get the data
|
||||
const { latLon } = LoadTwcData;
|
||||
const { latLon } = loadData;
|
||||
// if there's no data stop
|
||||
if (!latLon) return;
|
||||
|
||||
@@ -243,39 +239,39 @@ const swipeCallBack = (direction) => {
|
||||
|
||||
const btnNavigateRefreshClick = () => {
|
||||
resetStatuses();
|
||||
LoadTwcData();
|
||||
UpdateFullScreenNavigate();
|
||||
loadData();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const btnNavigateNextClick = () => {
|
||||
postMessage('navButton', 'next');
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const btnNavigatePreviousClick = () => {
|
||||
postMessage('navButton', 'previous');
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
let NavigateFadeIntervalId = null;
|
||||
let navigateFadeIntervalId = null;
|
||||
|
||||
const UpdateFullScreenNavigate = () => {
|
||||
const updateFullScreenNavigate = () => {
|
||||
document.activeElement.blur();
|
||||
document.getElementById('divTwcBottom').classList.remove('hidden');
|
||||
document.getElementById('divTwcBottom').classList.add('visible');
|
||||
|
||||
if (NavigateFadeIntervalId) {
|
||||
clearTimeout(NavigateFadeIntervalId);
|
||||
NavigateFadeIntervalId = null;
|
||||
if (navigateFadeIntervalId) {
|
||||
clearTimeout(navigateFadeIntervalId);
|
||||
navigateFadeIntervalId = null;
|
||||
}
|
||||
|
||||
NavigateFadeIntervalId = setTimeout(() => {
|
||||
navigateFadeIntervalId = setTimeout(() => {
|
||||
if (document.fullscreenElement) {
|
||||
document.getElementById('divTwcBottom').classList.remove('visible');
|
||||
document.getElementById('divTwcBottom').classList.add('hidden');
|
||||
@@ -324,11 +320,9 @@ const documentKeydown = (e) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
Math.round2 = (value, decimals) => Number(`${Math.round(`${value}e${decimals}`)}e-${decimals}`);
|
||||
|
||||
const btnNavigatePlayClick = () => {
|
||||
postMessage('navButton', 'playToggle');
|
||||
UpdateFullScreenNavigate();
|
||||
updateFullScreenNavigate();
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -363,13 +357,13 @@ const btnGetGpsClick = async () => {
|
||||
const { City } = data.address;
|
||||
const State = states.getTwoDigitCode(data.address.Region);
|
||||
const Country = data.address.CountryCode;
|
||||
const TwcQuery = `${ZipCode}, ${City}, ${State}, ${Country}`;
|
||||
const query = `${ZipCode}, ${City}, ${State}, ${Country}`;
|
||||
|
||||
const txtAddress = document.getElementById('txtAddress');
|
||||
txtAddress.value = TwcQuery;
|
||||
txtAddress.value = query;
|
||||
txtAddress.blur();
|
||||
txtAddress.focus();
|
||||
|
||||
// Save the query
|
||||
localStorage.setItem('TwcQuery', TwcQuery);
|
||||
localStorage.setItem('latLonQuery', query);
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ const buildForecast = (forecast, city, cityXY) => ({
|
||||
const getRegionalObservation = async (point, city) => {
|
||||
try {
|
||||
// get stations
|
||||
const stations = await json(`https://api.weather.gov/gridpoints/${city.point.wfo}/${city.point.x},${city.point.y}/stations`);
|
||||
const stations = await json(`https://api.weather.gov/gridpoints/${point.wfo}/${point.x},${point.y}/stations`);
|
||||
|
||||
// get the first station
|
||||
const station = stations.features[0].id;
|
||||
|
||||
@@ -11,6 +11,7 @@ import { DateTime } from '../vendor/auto/luxon.mjs';
|
||||
import WeatherDisplay from './weatherdisplay.mjs';
|
||||
import { registerDisplay } from './navigation.mjs';
|
||||
import * as utils from './regionalforecast-utils.mjs';
|
||||
import { getPoint } from './utils/weather.mjs';
|
||||
|
||||
class RegionalForecast extends WeatherDisplay {
|
||||
constructor(navId, elemId) {
|
||||
@@ -73,12 +74,13 @@ class RegionalForecast extends WeatherDisplay {
|
||||
// get regional forecasts and observations (the two are intertwined due to the design of api.weather.gov)
|
||||
const regionalDataAll = await Promise.all(regionalCities.map(async (city) => {
|
||||
try {
|
||||
if (!city.point) throw new Error('No pre-loaded point');
|
||||
const point = city?.point ?? (await getAndFormatPoint(city.lat, city.lon));
|
||||
if (!point) throw new Error('No pre-loaded point');
|
||||
|
||||
// start off the observation task
|
||||
const observationPromise = utils.getRegionalObservation(city.point, city);
|
||||
const observationPromise = utils.getRegionalObservation(point, city);
|
||||
|
||||
const forecast = await json(`https://api.weather.gov/gridpoints/${city.point.wfo}/${city.point.x},${city.point.y}/forecast`);
|
||||
const forecast = await json(`https://api.weather.gov/gridpoints/${point.wfo}/${point.x},${point.y}/forecast`);
|
||||
|
||||
// get XY on map for city
|
||||
const cityXY = utils.getXYForCity(city, minMaxLatLon.maxLat, minMaxLatLon.minLon, weatherParameters.state);
|
||||
@@ -192,5 +194,14 @@ class RegionalForecast extends WeatherDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
const getAndFormatPoint = async (lat, lon) => {
|
||||
const point = await getPoint(lat, lon);
|
||||
return {
|
||||
x: point.properties.gridX,
|
||||
y: point.properties.gridY,
|
||||
wfo: point.properties.gridId,
|
||||
};
|
||||
};
|
||||
|
||||
// register display
|
||||
registerDisplay(new RegionalForecast(5, 'regional-forecast'));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// *********************************** unit conversions ***********************
|
||||
|
||||
const round2 = (value, decimals) => Number(`${Math.round(`${value}e${decimals}`)}e-${decimals}`);
|
||||
const round2 = (value, decimals) => Math.trunc(value * 10 ** decimals) / 10 ** decimals;
|
||||
|
||||
const kphToMph = (Kph) => Math.round(Kph / 1.60934);
|
||||
const celsiusToFahrenheit = (Celsius) => Math.round((Celsius * 9) / 5 + 32);
|
||||
@@ -14,4 +14,5 @@ export {
|
||||
kilometersToMiles,
|
||||
metersToFeet,
|
||||
pascalToInHg,
|
||||
round2,
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ class WeatherDisplay {
|
||||
if (this.elemId === 'progress') return false;
|
||||
|
||||
// get the saved status of the checkbox
|
||||
let savedStatus = window.localStorage.getItem(`${this.elemId}Enabled`);
|
||||
let savedStatus = window.localStorage.getItem(`display-enabled: ${this.elemId}`);
|
||||
if (savedStatus === null) savedStatus = defaultEnabled;
|
||||
if (savedStatus === 'true' || savedStatus === true) {
|
||||
this.enabled = true;
|
||||
@@ -61,7 +61,7 @@ class WeatherDisplay {
|
||||
}
|
||||
|
||||
// refresh (or initially store the state of the checkbox)
|
||||
window.localStorage.setItem(`${this.elemId}Enabled`, this.enabled);
|
||||
window.localStorage.setItem(`display-enabled: ${this.elemId}`, this.enabled);
|
||||
|
||||
// create a checkbox in the selected displays area
|
||||
const checkbox = document.createElement('template');
|
||||
@@ -77,7 +77,7 @@ class WeatherDisplay {
|
||||
// update the state
|
||||
this.enabled = e.target.checked;
|
||||
// store the value for the next load
|
||||
window.localStorage.setItem(`${this.elemId}Enabled`, this.enabled);
|
||||
window.localStorage.setItem(`display-enabled: ${this.elemId}`, this.enabled);
|
||||
// calling get data will update the status and actually get the data if we're set to enabled
|
||||
this.getData();
|
||||
}
|
||||
|
||||
196
server/scripts/vendor/jeoquery.js
vendored
196
server/scripts/vendor/jeoquery.js
vendored
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* jeoQuery v0.5.1
|
||||
*
|
||||
* Copyright 2012-2038, Thomas Haukland
|
||||
* MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
var jeoquery = (function ($) {
|
||||
var my = {};
|
||||
|
||||
my.defaultData = {
|
||||
userName: 'vbguyny',
|
||||
lang: 'en'
|
||||
};
|
||||
my.defaultCountryCode = 'US';
|
||||
my.defaultLanguage = 'en';
|
||||
my.geoNamesApiServer = 'api.geonames.org';
|
||||
my.geoNamesProtocol = 'http';
|
||||
|
||||
my.featureClass = {
|
||||
AdministrativeBoundary: 'A',
|
||||
Hydrographic: 'H',
|
||||
Area: 'L',
|
||||
PopulatedPlace: 'P',
|
||||
RoadRailroad: 'R',
|
||||
Spot: 'S',
|
||||
Hypsographic: 'T',
|
||||
Undersea: 'U',
|
||||
Vegetation: 'V'
|
||||
};
|
||||
|
||||
my.getGeoNames = function(method, data, callback, errorcallback) {
|
||||
var deferred = $.Deferred();
|
||||
if (!method || !methods[method]) {
|
||||
throw 'Invalid geonames method "' + method + '".';
|
||||
}
|
||||
$.ajax({
|
||||
url: my.geoNamesProtocol + '://' + my.geoNamesApiServer + '/' + method + 'JSON',
|
||||
dataType: 'jsonp',
|
||||
data: $.extend({}, my.defaultData, data),
|
||||
// GeoNames expects "traditional" param serializing
|
||||
traditional: true,
|
||||
success: function(data) {
|
||||
deferred.resolve(data);
|
||||
if (!!callback) callback(data);
|
||||
},
|
||||
error: function (xhr, textStatus) {
|
||||
deferred.reject(xhr, textStatus);
|
||||
//alert('Ooops, geonames server returned: ' + textStatus);
|
||||
if (!!errorcallback) errorcallback(textStatus);
|
||||
}
|
||||
});
|
||||
return deferred.promise();
|
||||
};
|
||||
|
||||
function formatDate(date) {
|
||||
var dateQs = '';
|
||||
if (date) {
|
||||
dateQs = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
|
||||
}
|
||||
return dateQs;
|
||||
}
|
||||
|
||||
var methods = {
|
||||
astergdem: {params: ['lat', 'lng'] },
|
||||
children: {params: ['geonameId', 'maxRows'] },
|
||||
cities: {params: ['north', 'south', 'east', 'west', 'lang'] },
|
||||
countryCode: {params: ['lat', 'lng', 'type', 'lang', 'radius'] },
|
||||
countryInfo: {params: ['country', 'lang'] },
|
||||
countrySubdivision: {params: ['lat', 'lng', 'level', 'lang', 'radius'] },
|
||||
earthquakes: {params: ['north', 'south', 'east', 'west', 'date', 'maxRows', 'minMagnitude'] },
|
||||
findNearby: {params: ['lat', 'lng', 'featureClass', 'featureCode', 'radius', 'style', 'maxRows'] },
|
||||
findNearbyPlacename: {params: ['lat', 'lng', 'radius', 'style'] },
|
||||
findNearbyPostalCodes: {params: ['lat', 'lng', 'radius', 'style', 'maxRows', 'country', 'localCountry', 'postalCode'] },
|
||||
findNearbyStreets: {params: ['lat', 'lng', 'radius', 'maxRows'] },
|
||||
findNearbyStreetsOSM: {params: ['lat', 'lng'] },
|
||||
findNearbyWeather: {params: ['lat', 'lng'] },
|
||||
findNearbyWikipedia: {params: ['lat', 'lng', 'radius', 'maxRows', 'country', 'postalCode'] },
|
||||
findNearestAddress: {params: ['lat', 'lng'] },
|
||||
findNearestIntersection: {params: ['lat', 'lng'] },
|
||||
findNearestIntersectionOSM: {params: ['lat', 'lng', 'radius', 'maxRows'] },
|
||||
findNearbyPOIsOSM: {params: ['lat', 'lng'] },
|
||||
get: {params: ['geonameId', 'lang', 'style'] },
|
||||
gtopo30: {params: ['lat', 'lng'] },
|
||||
hierarchy: {params: ['geonameId'] },
|
||||
neighbourhood: {params: ['lat', 'lng'] },
|
||||
neighbours: {params: ['geonameId', 'country'] },
|
||||
ocean: {params: ['lat', 'lng', 'radius'] },
|
||||
postalCodeCountryInfo: {params: [] },
|
||||
postalCodeLookup: {params: ['postalcode', 'country', 'maxRows', 'charset'] },
|
||||
postalCodeSearch: {params: ['postalcode', 'postalcode_startsWith', 'placename_startsWith', 'country', 'countryBias', 'maxRows', 'style', 'operator', 'charset', 'isReduced'] },
|
||||
search: {params: [ 'q', 'name', 'name_equals', 'name_startsWith', 'maxRows', 'startRow', 'country', 'countryBias', 'continentCode', 'adminCode1', 'adminCode2', 'adminCode3', 'featureClass', 'featureCode', 'lang', 'type', 'style', 'isNameRequired', 'tag', 'operator', 'charset', 'fuzzy'] },
|
||||
siblings: {params: ['geonameId'] },
|
||||
srtm3: {params: ['lat', 'lng'] },
|
||||
timezone: {params: ['lat', 'lng', 'radius', 'date'] },
|
||||
weather: {params: ['north', 'south', 'east', 'west', 'maxRows'] },
|
||||
weatherIcao: {params: ['ICAO'] },
|
||||
wikipediaBoundingBox: {params: ['north', 'south', 'east', 'west', 'lang', 'maxRows'] },
|
||||
wikipediaSearch: {params: ['q', 'title', 'lang', 'maxRows'] }
|
||||
};
|
||||
|
||||
return my;
|
||||
}(jQuery));
|
||||
|
||||
(function ($) {
|
||||
$.fn.jeoCountrySelect = function (options) {
|
||||
var el = this;
|
||||
$.when(jeoquery.getGeoNames('countryInfo'))
|
||||
.then(function (data) {
|
||||
var sortedNames = data.geonames;
|
||||
if (data.geonames.sort) {
|
||||
sortedNames = data.geonames.sort(function (a, b) {
|
||||
return a.countryName.localeCompare(b.countryName);
|
||||
});
|
||||
}
|
||||
// Insert blank choice
|
||||
sortedNames.unshift({countryCode:'', countryName:''});
|
||||
var html = $.map(sortedNames, function(c) {
|
||||
return '<option value="' + c.countryCode + '">' + c.countryName + '</option>';
|
||||
});
|
||||
el.html(html);
|
||||
if (options && options.callback) options.callback(sortedNames);
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.jeoPostalCodeLookup = function (options) {
|
||||
this.on("change", function () {
|
||||
var code = $(this).val();
|
||||
var country = options.country || jeoquery.defaultCountryCode;
|
||||
if (options.countryInput) {
|
||||
country = options.countryInput.val() || jeoquery.defaultCountry;
|
||||
}
|
||||
if (code) {
|
||||
jeoquery.getGeoNames('postalCodeLookup', {postalcode: code, country: country}, function (data) {
|
||||
if (data && data.postalcodes && data.postalcodes.length > 0) {
|
||||
if (options) {
|
||||
if (options.target) {
|
||||
options.target.val(data.postalcodes[0].placeName);
|
||||
}
|
||||
if (options.callback) {
|
||||
options.callback(data.postalcodes[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.jeoCityAutoComplete = function (options) {
|
||||
this.autocomplete({
|
||||
source: function (request, response) {
|
||||
jeoquery.getGeoNames('search', {
|
||||
featureClass: jeoquery.featureClass.PopulatedPlace,
|
||||
style: ((options && options.style) ? options.style : "medium"),
|
||||
maxRows: 12,
|
||||
name_startsWith: request.term
|
||||
}, function (data) {
|
||||
response(function() {
|
||||
data.geonames = $.map(data.geonames, function (item) {
|
||||
var displayName = item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName;
|
||||
if (options && options.displayNameFunc) {
|
||||
displayName = options.displayNameFunc(item);
|
||||
if (displayName === null)
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
label: displayName,
|
||||
value: displayName,
|
||||
details: item
|
||||
};
|
||||
});
|
||||
if (options && options.preProcessResults) {
|
||||
options.preProcessResults(data.geonames);
|
||||
}
|
||||
return data.geonames;
|
||||
}());
|
||||
});
|
||||
},
|
||||
minLength: 2,
|
||||
select: function( event, ui ) {
|
||||
if (ui && ui.item && options && options.callback) {
|
||||
options.callback(ui.item.details);
|
||||
}
|
||||
},
|
||||
open: function () {
|
||||
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
|
||||
},
|
||||
close: function () {
|
||||
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -50,5 +50,10 @@
|
||||
"[html]": {
|
||||
"editor.defaultFormatter": "j69.ejs-beautify"
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/debug.log": true,
|
||||
"server/scripts/custom.js": true
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user