Примечание. Этот модуль хранит все данные в памяти — помните об этом.
Uber быстрый поиск ближайших мест по координатам.
Поддерживает Array
, Object
, JSON
и GeoJSON
в качестве входных данных.
$ npm install geo-nearby --save
const Geo = require ( 'geo-nearby' ) ;
const dataSet = [
{ i : 'Perth' , g : 3149853951719405 } ,
{ i : 'Adelaide' , g : 3243323516150966 } ,
{ i : 'Melbourne' , g : 3244523307653507 } ,
{ i : 'Canberra' , g : 3251896081369449 } ,
{ i : 'Sydney' , g : 3252342838034651 } ,
{ i : 'Brisbane' , g : 3270013708086451 } ,
{ i : 'Sydney' , g : 3252342838034651 }
] ;
const geo = new Geo ( dataSet ) ;
geo . nearBy ( - 33.87 , 151.2 , 5000 ) ; // 5000 - 5km
В g
хранится геохеш с точностью до 52 бит.
Если вы хотите изменить имя свойства, вы можете сделать это с помощью опций:
const Geo = require ( 'geo-nearby' ) ;
const dataSet = [
{ id : 1 , name : 'Perth' , geoHash : 3149853951719405 } ,
{ id : 2 , name : 'Adelaide' , geoHash : 3243323516150966 } ,
{ id : 3 , name : 'Melbourne' , geoHash : 3244523307653507 } ,
{ id : 4 , name : 'Canberra' , geoHash : 3251896081369449 } ,
{ id : 5 , name : 'Sydney' , geoHash : 3252342838034651 } ,
{ id : 6 , name : 'Brisbane' , geoHash : 3270013708086451 } ,
{ id : 7 , name : 'Sydney' , geoHash : 3252342838034651 }
] ;
const geo = new Geo ( dataSet , { hash : 'geoHash' } ) ;
geo . nearBy ( - 33.87 , 151.2 , 5000 ) ;
Для лучшей производительности рекомендуется использовать синтаксис набора данных по умолчанию:
const dataSet = [
...
{ i : < id > , g: < geo hash > } ,
{ i : < id > , g : < geo hash > } ,
...
];
Вы можете использовать метод createCompactSet
для создания набора данных с рекомендуемым синтаксисом ваших данных:
const data = [
[ - 35.30278 , 149.14167 , 'Canberra' ] ,
[ - 33.86944 , 151.20833 , 'Sydney' ] ,
[ - 37.82056 , 144.96139 , 'Melbourne' ] ,
[ - 34.93333 , 138.58333 , 'Adelaide' ] ,
[ - 27.46778 , 153.02778 , 'Brisbane' ] ,
[ - 31.95306 , 115.85889 , 'Perth' ]
] ;
const dataSet = Geo . createCompactSet ( data ) ;
const geo = new Geo ( dataSet , { sorted : true } ) ;
geo . nearBy ( - 33.87 , 151.2 , 5000 ) ;
createCompactSet
поддерживает Array
, разобранный и неразобранный JSON
, разобранный и неразобранный GeoJSON
в качестве входных данных:
const data = {
type : 'FeatureCollection' ,
features : [
{ type : 'Feature' , geometry : { type : 'Point' , coordinates : [ 44 , 64 ] } , properties : { name : 'Arkhangelskaya Oblast' } } ,
{ type : 'Feature' , geometry : { type : 'Point' , coordinates : [ 40.5433 , 64.5401 ] } , properties : { name : 'Arkhangelsk' } } ,
{ type : 'Feature' , geometry : { type : 'Point' , coordinates : [ 39.8302 , 64.5635 ] } , properties : { name : 'Severodvinsk' } } ,
{ type : 'Feature' , geometry : { type : 'Point' , coordinates : [ 40.8122 , 64.4165 ] } , properties : { name : 'Novodvinsk' } } ,
{ type : 'Feature' , geometry : { type : 'Point' , coordinates : [ 46.64963 , 61.25745 ] } , properties : { name : 'Kotlas' } }
]
} ;
const dataSet = Geo . createCompactSet ( data , { id : 'name' } ) ;
const geo = new Geo ( dataSet , { sorted : true } ) ;
geo . nearBy ( 64.54 , 40.54 , 5000 ) ;
Вы также можете изменить значения по умолчанию для метода createCompactSet
, если ваши данные выглядят иначе:
const data = [
{ _id : 1000 , name : 'Arkhangel’skaya Oblast’' , country : 'RU' , coord : { lon : 44 , lat : 64 } , admin1 : 'Arkhangelskaya' } ,
{ _id : 1001 , name : 'Arkhangelsk' , country : 'RU' , coord : { lon : 40.5433 , lat : 64.5401 } , admin1 : 'Arkhangelskaya' } ,
{ _id : 1002 , name : 'Severodvinsk' , country : 'RU' , coord : { lon : 39.8302 , lat : 64.5635 } , admin1 : 'Arkhangelskaya' } ,
{ _id : 1003 , name : 'Novodvinsk' , country : 'RU' , coord : { lon : 40.8122 , lat : 64.4165 } , admin1 : 'Arkhangelskaya' } ,
{ _id : 1004 , name : 'Kotlas' , country : 'RU' , coord : { lon : 46.64963 , lat : 61.25745 } , admin1 : 'Arkhangelskaya' }
] ;
const dataSet = Geo . createCompactSet ( data , { id : '_id' , lat : [ 'coord' , 'lat' ] , lon : [ 'coord' , 'lon' ] } ) ;
const geo = new Geo ( dataSet , { sorted : true } ) ;
geo . nearBy ( 64.54 , 40.54 , 5000 ) ;
Вы можете указать свойство setOptions
в options
конструктора, оно автоматически создаст набор данных, но для больших данных это может занять много времени:
const data = [
{ lat : - 35.30278 , lon : 149.14167 , name : 'Canberra' } ,
{ lat : - 33.86944 , lon : 151.20833 , name : 'Sydney' } ,
{ lat : - 37.82056 , lon : 144.96139 , name : 'Melbourne' } ,
{ lat : - 34.93333 , lon : 138.58333 , name : 'Adelaide' } ,
{ lat : - 27.46778 , lon : 153.02778 , name : 'Brisbane' } ,
{ lat : - 31.95306 , lon : 115.85889 , name : 'Perth' }
] ;
const geo = new Geo ( data , { setOptions : { id : 'name' , lat : 'lat' , lon : 'lon' } } ) ;
geo . nearBy ( - 33.87 , 151.2 , 5000 ) ;
Если у вас огромные данные, возможно, разумнее сохранить их в файл:
const data = require ( './huge.data.set.file.json' ) ;
Geo . createCompactSet ( { id : '_id' , lat : 'lat' , lon : 'lon' , file : './compact.set.json' } ) ;
И затем загрузите переменную:
const dataSet = require ( './compact.set.json' ) ;
const geo = new Geo ( dataSet , { sorted : true } ) ;
geo . nearBy ( 64.54 , 40.54 , 5000 ) ;
Для ограничения результатов у вас есть два пути:
1. Определите лимит в настройках. Это позволяет вам определить постоянный лимит результатов.
const geo = new Geo ( dataSet , { limit : 1 } ) ;
geo . nearBy ( 64.54 , 40.54 , 3000 ) ;
new Geo ( dataSet , { limit : 1 } ) . nearBy ( 64.54 , 40.54 , 3000 ) ;
geo . nearBy ( - 33.87 , 151.2 , 5000 ) ;
Во всех этих случаях результаты будут ограничены 1.
2. Определите лимит с помощью метода limit()
. Это позволяет вам определить временный предел результатов.
const foo = new Geo ( dataSet ) . limit ( 1 ) ;
foo . nearBy ( 64.54 , 40.54 , 5000 ) ; //up to 1
foo . nearBy ( 64.54 , 40.54 , 5000 ) ; //no limits
const bar = new Geo ( dataSet , { limit : 1 } ) . limit ( 10 ) ;
bar . nearBy ( 64.54 , 40.54 , 5000 ) ; //up to 10
bar . nearBy ( 64.54 , 40.54 , 5000 ) ; //up to 1. Options limit - permanent limit.
bar . limit ( 2 ) . nearBy ( 64.54 , 40.54 , 5000 ) ; //up to 2
Для более точного определения можно использовать диапазон расстояний. Это немного медленнее, но точнее.
const geo = new Geo ( dataSet ) ;
geo . limit ( 2 ) . nearBy ( 64.54 , 40.54 , [ 250 , 30000 ] ) ;
Примечание. Не используйте слишком маленькое расстояние для начального значения. Для значений менее 250 выполнение скрипта может занять слишком много времени для несортированного набора данных. Обычно достаточно 250-500.
Если вы создали набор данных методом createCompactSet
или ваш собственный набор данных отсортирован по свойству geohash
в порядке возрастания, вы можете активировать чрезвычайно быстрый двоичный поиск.
Просто установите для свойства sorted
значение true
в options
конструктора.
Бинарный поиск в 20 раз быстрее обычного.
const geo = new Geo ( dataSet , { sorted : true } ) ;
geo . limit ( 1 ) . nearBy ( 64.54 , 40.54 , [ 250 , 30000 ] ) ;
Если у вас есть набор данных (с рекомендуемым синтаксисом), который не отсортирован, вы можете легко его отсортировать, просто установите для свойства sort
значение true
в options
конструктора.
Набор данных будет автоматически отсортирован с использованием алгоритма быстрой внутренней сортировки. Но имейте в виду, сортировка займет некоторое время.
В некоторых случаях поиск в несортированном наборе данных будет быстрее, чем сортировка и поиск.
const geo = new Geo ( dataSet , { sort : true } ) ;
geo . limit ( 1 ) . nearBy ( 64.54 , 40.54 , [ 250 , 30000 ] ) ;
Конструктор.
sorted
как true
это включит двоичный поиск (сверхбыстрый режим)hash
сверху) const geo = new Geo ( dataSet , { hash : 'geo' , limit : 1 , sorted : true } ) ;
Метод поиска близлежащих мест.
const geo = new Geo ( dataSet ) ;
geo . nearBy ( 64.54 , 40.54 , [ 500 , 300000 ] ) ;
Временный лимит на результаты.
const geo = new Geo ( dataSet ) ;
geo . limit ( 1 ) . nearBy ( 64.54 , 40.54 , [ 500 , 300000 ] ) ;
Метод создает набор данных.
Статический метод.
const dataSet = Geo . createCompactSet ( data , { id : [ 'names' , 'name' , 'id' ] } ) ;
Лицензия MIT (MIT)
Copyright (c) 2015-2016 Алексей Быстров