@hebcal/geo-sqlite 4.0.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/geo-sqlite v4.0.1 */
1
+ /*! @hebcal/geo-sqlite v4.3.0 */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -222,6 +222,7 @@ class GeoDb {
222
222
  const cityDescr = `${result.CityMixedCase}, ${result.State} ${zip}`;
223
223
  const location = new core.Location(result.Latitude, result.Longitude, false, tzid, cityDescr, 'US', zip);
224
224
  location.admin1 = location.state = result.State;
225
+ location.stateName = stateNames[location.state];
225
226
  location.geo = 'zip';
226
227
  location.zip = zip;
227
228
  return location;
@@ -305,33 +306,39 @@ class GeoDb {
305
306
  /**
306
307
  * @private
307
308
  * @param {any[]} res
309
+ * @param {boolean} latlong
308
310
  * @return {Object[]}
309
311
  */
310
312
 
311
313
 
312
- static zipResultToObj(res) {
314
+ static zipResultToObj(res, latlong = false) {
313
315
  const obj = {
314
316
  id: String(res.ZipCode),
315
317
  value: `${res.CityMixedCase}, ${res.State} ${res.ZipCode}`,
316
318
  admin1: res.State,
317
319
  asciiname: res.CityMixedCase,
318
320
  country: 'United States',
319
- latitude: res.Latitude,
320
- longitude: res.Longitude,
321
- timezone: core.Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving),
322
321
  population: res.Population,
323
322
  geo: 'zip'
324
323
  };
324
+
325
+ if (latlong) {
326
+ obj.latitude = res.Latitude;
327
+ obj.longitude = res.Longitude;
328
+ obj.timezone = core.Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving);
329
+ }
330
+
325
331
  return obj;
326
332
  }
327
333
  /**
328
334
  * Generates autocomplete results based on a query string
329
335
  * @param {string} qraw
336
+ * @param {boolean} latlong
330
337
  * @return {Object[]}
331
338
  */
332
339
 
333
340
 
334
- autoComplete(qraw) {
341
+ autoComplete(qraw, latlong = false) {
335
342
  qraw = qraw.trim();
336
343
 
337
344
  if (qraw.length === 0) {
@@ -346,7 +353,7 @@ class GeoDb {
346
353
  }
347
354
 
348
355
  const zip5 = qraw.substring(0, 5);
349
- return this.zipCompStmt.all(zip5 + '%').map(GeoDb.zipResultToObj);
356
+ return this.zipCompStmt.all(zip5 + '%').map(row => GeoDb.zipResultToObj(row, latlong));
350
357
  } else {
351
358
  if (!this.geonamesCompStmt) {
352
359
  this.geonamesCompStmt = this.geonamesDb.prepare(GEONAME_COMPLETE_SQL);
@@ -361,11 +368,6 @@ class GeoDb {
361
368
  id: res.geonameid,
362
369
  value: core.Location.geonameCityDescr(res.asciiname, admin1, country),
363
370
  asciiname: res.asciiname,
364
- admin1,
365
- country,
366
- latitude: res.latitude,
367
- longitude: res.longitude,
368
- timezone: res.timezone,
369
371
  population: res.population,
370
372
  geo: 'geoname'
371
373
  };
@@ -378,7 +380,12 @@ class GeoDb {
378
380
  obj.admin1 = admin1;
379
381
  }
380
382
 
381
- obj.tokens = Array.from(new Set(res.asciiname.split(' ').concat(admin1.split(' '), country.split(' '))));
383
+ if (latlong) {
384
+ obj.latitude = res.latitude;
385
+ obj.longitude = res.longitude;
386
+ obj.timezone = res.timezone;
387
+ }
388
+
382
389
  return obj;
383
390
  });
384
391
 
@@ -387,7 +394,7 @@ class GeoDb {
387
394
  }
388
395
 
389
396
  const zipRows = this.zipFulltextCompStmt.all(`"${qraw}*"`);
390
- const zipMatches = zipRows.map(GeoDb.zipResultToObj);
397
+ const zipMatches = zipRows.map(row => GeoDb.zipResultToObj(row, latlong));
391
398
  const map = new Map();
392
399
 
393
400
  for (const obj of zipMatches) {
@@ -549,6 +556,12 @@ async function buildGeonamesSqlite(opts) {
549
556
  periodTo NULL
550
557
  );`);
551
558
  await doFile(logger, db, ILalternate, 'alternatenames', 10, a => {
559
+ const firstchar = a[3][0];
560
+
561
+ if (a[2] === 'he' && (firstchar < '\u05D0' || firstchar > '\u05EA')) {
562
+ a[2] = 'en';
563
+ }
564
+
552
565
  if (a[2] === 'he' || a[2] === 'en') {
553
566
  if (a[2] === 'he') {
554
567
  a[3] = a[3].replace(/‘/g, '׳');
@@ -558,6 +571,13 @@ async function buildGeonamesSqlite(opts) {
558
571
  } else {
559
572
  a[3] = a[3].replace(/‘/g, '\'');
560
573
  a[3] = a[3].replace(/’/g, '\'');
574
+ a[3] = a[3].replace(/Ḥ/g, 'Ch');
575
+ a[3] = a[3].replace(/H̱/g, 'Ch');
576
+ a[3] = a[3].replace(/ẖ/g, 'ch');
577
+ a[3] = a[3].replace(/Ẕ/g, 'Tz');
578
+ a[3] = a[3].replace(/ẕ/g, 'tz');
579
+ a[3] = a[3].replace(/ā/g, 'a');
580
+ a[3] = a[3].replace(/é/g, 'e');
561
581
  }
562
582
 
563
583
  return true;
@@ -604,11 +624,20 @@ async function buildGeonamesSqlite(opts) {
604
624
  SELECT g.geonameid, alt.name||', ישראל',
605
625
  alt.name, '', 'ישראל',
606
626
  g.population, g.latitude, g.longitude, g.timezone
607
- FROM geoname g, country c, altnames alt
627
+ FROM geoname g, altnames alt
608
628
  WHERE g.country = 'IL'
609
629
  AND alt.isolanguage = 'he'
610
630
  AND g.geonameid = alt.geonameid
611
- `);
631
+ `, `INSERT INTO geoname_fulltext
632
+ SELECT g.geonameid, alt.name||', '||a1.asciiname||', Israel',
633
+ alt.name, a1.asciiname, 'Israel',
634
+ g.population, g.latitude, g.longitude, g.timezone
635
+ FROM geoname g, admin1 a1, altnames alt
636
+ WHERE g.country = 'IL'
637
+ AND alt.isolanguage = 'en'
638
+ AND g.geonameid = alt.geonameid
639
+ AND g.country||'.'||g.admin1 = a1.key
640
+ `, 'VACUUM');
612
641
  db.close();
613
642
  return Promise.resolve(true);
614
643
  }
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/geo-sqlite v4.0.1 */
1
+ /*! @hebcal/geo-sqlite v4.3.0 */
2
2
  import Database from 'better-sqlite3';
3
3
  import { Location, Locale } from '@hebcal/core';
4
4
  import '@hebcal/cities';
@@ -210,6 +210,7 @@ class GeoDb {
210
210
  const cityDescr = `${result.CityMixedCase}, ${result.State} ${zip}`;
211
211
  const location = new Location(result.Latitude, result.Longitude, false, tzid, cityDescr, 'US', zip);
212
212
  location.admin1 = location.state = result.State;
213
+ location.stateName = stateNames[location.state];
213
214
  location.geo = 'zip';
214
215
  location.zip = zip;
215
216
  return location;
@@ -293,33 +294,39 @@ class GeoDb {
293
294
  /**
294
295
  * @private
295
296
  * @param {any[]} res
297
+ * @param {boolean} latlong
296
298
  * @return {Object[]}
297
299
  */
298
300
 
299
301
 
300
- static zipResultToObj(res) {
302
+ static zipResultToObj(res, latlong = false) {
301
303
  const obj = {
302
304
  id: String(res.ZipCode),
303
305
  value: `${res.CityMixedCase}, ${res.State} ${res.ZipCode}`,
304
306
  admin1: res.State,
305
307
  asciiname: res.CityMixedCase,
306
308
  country: 'United States',
307
- latitude: res.Latitude,
308
- longitude: res.Longitude,
309
- timezone: Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving),
310
309
  population: res.Population,
311
310
  geo: 'zip'
312
311
  };
312
+
313
+ if (latlong) {
314
+ obj.latitude = res.Latitude;
315
+ obj.longitude = res.Longitude;
316
+ obj.timezone = Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving);
317
+ }
318
+
313
319
  return obj;
314
320
  }
315
321
  /**
316
322
  * Generates autocomplete results based on a query string
317
323
  * @param {string} qraw
324
+ * @param {boolean} latlong
318
325
  * @return {Object[]}
319
326
  */
320
327
 
321
328
 
322
- autoComplete(qraw) {
329
+ autoComplete(qraw, latlong = false) {
323
330
  qraw = qraw.trim();
324
331
 
325
332
  if (qraw.length === 0) {
@@ -334,7 +341,7 @@ class GeoDb {
334
341
  }
335
342
 
336
343
  const zip5 = qraw.substring(0, 5);
337
- return this.zipCompStmt.all(zip5 + '%').map(GeoDb.zipResultToObj);
344
+ return this.zipCompStmt.all(zip5 + '%').map(row => GeoDb.zipResultToObj(row, latlong));
338
345
  } else {
339
346
  if (!this.geonamesCompStmt) {
340
347
  this.geonamesCompStmt = this.geonamesDb.prepare(GEONAME_COMPLETE_SQL);
@@ -349,11 +356,6 @@ class GeoDb {
349
356
  id: res.geonameid,
350
357
  value: Location.geonameCityDescr(res.asciiname, admin1, country),
351
358
  asciiname: res.asciiname,
352
- admin1,
353
- country,
354
- latitude: res.latitude,
355
- longitude: res.longitude,
356
- timezone: res.timezone,
357
359
  population: res.population,
358
360
  geo: 'geoname'
359
361
  };
@@ -366,7 +368,12 @@ class GeoDb {
366
368
  obj.admin1 = admin1;
367
369
  }
368
370
 
369
- obj.tokens = Array.from(new Set(res.asciiname.split(' ').concat(admin1.split(' '), country.split(' '))));
371
+ if (latlong) {
372
+ obj.latitude = res.latitude;
373
+ obj.longitude = res.longitude;
374
+ obj.timezone = res.timezone;
375
+ }
376
+
370
377
  return obj;
371
378
  });
372
379
 
@@ -375,7 +382,7 @@ class GeoDb {
375
382
  }
376
383
 
377
384
  const zipRows = this.zipFulltextCompStmt.all(`"${qraw}*"`);
378
- const zipMatches = zipRows.map(GeoDb.zipResultToObj);
385
+ const zipMatches = zipRows.map(row => GeoDb.zipResultToObj(row, latlong));
379
386
  const map = new Map();
380
387
 
381
388
  for (const obj of zipMatches) {
@@ -537,6 +544,12 @@ async function buildGeonamesSqlite(opts) {
537
544
  periodTo NULL
538
545
  );`);
539
546
  await doFile(logger, db, ILalternate, 'alternatenames', 10, a => {
547
+ const firstchar = a[3][0];
548
+
549
+ if (a[2] === 'he' && (firstchar < '\u05D0' || firstchar > '\u05EA')) {
550
+ a[2] = 'en';
551
+ }
552
+
540
553
  if (a[2] === 'he' || a[2] === 'en') {
541
554
  if (a[2] === 'he') {
542
555
  a[3] = a[3].replace(/‘/g, '׳');
@@ -546,6 +559,13 @@ async function buildGeonamesSqlite(opts) {
546
559
  } else {
547
560
  a[3] = a[3].replace(/‘/g, '\'');
548
561
  a[3] = a[3].replace(/’/g, '\'');
562
+ a[3] = a[3].replace(/Ḥ/g, 'Ch');
563
+ a[3] = a[3].replace(/H̱/g, 'Ch');
564
+ a[3] = a[3].replace(/ẖ/g, 'ch');
565
+ a[3] = a[3].replace(/Ẕ/g, 'Tz');
566
+ a[3] = a[3].replace(/ẕ/g, 'tz');
567
+ a[3] = a[3].replace(/ā/g, 'a');
568
+ a[3] = a[3].replace(/é/g, 'e');
549
569
  }
550
570
 
551
571
  return true;
@@ -592,11 +612,20 @@ async function buildGeonamesSqlite(opts) {
592
612
  SELECT g.geonameid, alt.name||', ישראל',
593
613
  alt.name, '', 'ישראל',
594
614
  g.population, g.latitude, g.longitude, g.timezone
595
- FROM geoname g, country c, altnames alt
615
+ FROM geoname g, altnames alt
596
616
  WHERE g.country = 'IL'
597
617
  AND alt.isolanguage = 'he'
598
618
  AND g.geonameid = alt.geonameid
599
- `);
619
+ `, `INSERT INTO geoname_fulltext
620
+ SELECT g.geonameid, alt.name||', '||a1.asciiname||', Israel',
621
+ alt.name, a1.asciiname, 'Israel',
622
+ g.population, g.latitude, g.longitude, g.timezone
623
+ FROM geoname g, admin1 a1, altnames alt
624
+ WHERE g.country = 'IL'
625
+ AND alt.isolanguage = 'en'
626
+ AND g.geonameid = alt.geonameid
627
+ AND g.country||'.'||g.admin1 = a1.key
628
+ `, 'VACUUM');
600
629
  db.close();
601
630
  return Promise.resolve(true);
602
631
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hebcal/geo-sqlite",
3
- "version": "4.0.1",
3
+ "version": "4.3.0",
4
4
  "author": "Michael J. Radwin (https://github.com/mjradwin)",
5
5
  "keywords": [
6
6
  "hebcal"
@@ -28,10 +28,10 @@
28
28
  "geo-sqlite.d.ts"
29
29
  ],
30
30
  "dependencies": {
31
- "@hebcal/cities": "^3.1.1",
31
+ "@hebcal/cities": "^3.1.2",
32
32
  "@hebcal/core": "^3.33.3",
33
33
  "better-sqlite3": "^7.5.0",
34
- "pino": "^7.8.0",
34
+ "pino": "^7.8.1",
35
35
  "pino-pretty": "^7.5.3"
36
36
  },
37
37
  "scripts": {
@@ -60,11 +60,11 @@
60
60
  "@rollup/plugin-commonjs": "^21.0.2",
61
61
  "@rollup/plugin-json": "^4.1.0",
62
62
  "@rollup/plugin-node-resolve": "^13.1.3",
63
- "ava": "^4.0.1",
64
- "eslint": "^8.10.0",
63
+ "ava": "^4.1.0",
64
+ "eslint": "^8.11.0",
65
65
  "eslint-config-google": "^0.14.0",
66
66
  "jsdoc": "^3.6.10",
67
67
  "jsdoc-to-markdown": "^7.1.1",
68
- "rollup": "^2.69.0"
68
+ "rollup": "^2.70.0"
69
69
  }
70
70
  }