新聞中心
Redis電子圍欄是一種基于Redis實(shí)現(xiàn)的地理圍欄服務(wù),可以幫助我們?cè)谔幚砦恢孟嚓P(guān)的數(shù)據(jù)時(shí)更加方便和高效地實(shí)現(xiàn)某些功能。例如,在處理移動(dòng)設(shè)備的位置信息時(shí),我們可以使用這個(gè)服務(wù)來判斷設(shè)備是否進(jìn)入或離開了某個(gè)區(qū)域,進(jìn)而觸發(fā)相應(yīng)的業(yè)務(wù)邏輯。

海勃灣網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
然而,Redis電子圍欄目前只支持圓形和矩形兩種類型的圍欄,如果需要實(shí)現(xiàn)更加復(fù)雜的圍欄形狀,比如多邊形、線段等,就需要進(jìn)行一些擴(kuò)展和改進(jìn)。本文將介紹一種基于Redis和其他技術(shù)實(shí)現(xiàn)的電子圍欄的延伸方案,可以支持更多類型的圍欄形狀和更靈活的查詢方式。
方案介紹
我們的方案基于Redis的zset數(shù)據(jù)類型,利用其有序集合的特性實(shí)現(xiàn)電子圍欄服務(wù)。每個(gè)圍欄形狀都被抽象成了一個(gè)有序集合,在這個(gè)有序集合中,存儲(chǔ)了一系列的地理數(shù)據(jù)點(diǎn),這些點(diǎn)構(gòu)成了一個(gè)閉合的多邊形(或其他所需的形狀),表示了圍欄的邊界。
例如,下面展示了一個(gè)五邊形的圍欄:
127.0.0.1:6379> ZRANGE polygon_fenc 0 -1 WITHSCORES
1) "POINT(120.13525 30.26715)"
2) "0"
3) "POINT(120.13695 30.26703)"
4) "0"
5) "POINT(120.13747 30.26655)"
6) "0"
7) "POINT(120.13685 30.26588)"
8) "0"
9) "POINT(120.13522 30.26600)"
10) "0"
11) "POINT(120.13525 30.26715)"
12) "0"
可以看到,這個(gè)有序集合中存儲(chǔ)了六個(gè)地理數(shù)據(jù)點(diǎn),前五個(gè)點(diǎn)構(gòu)成了一個(gè)五邊形,最后一個(gè)點(diǎn)是為了閉合多邊形而添加的一個(gè)點(diǎn)。
為了判斷一個(gè)位置點(diǎn)是否在圍欄內(nèi),我們需要進(jìn)行一些計(jì)算工作。具體來說,我們可以借助開源的GeoHash算法,將圍欄邊界中的每個(gè)點(diǎn)表示為一個(gè)GeoHash值,并將這些值都存儲(chǔ)在一個(gè)bitmap中。當(dāng)需要判斷一個(gè)位置點(diǎn)是否在圍欄內(nèi)時(shí),我們將其也表示為一個(gè)GeoHash值,并查詢對(duì)應(yīng)的bitmap,如果這個(gè)位置點(diǎn)對(duì)應(yīng)的bitmap值為1,則說明該位置點(diǎn)在圍欄內(nèi),否則在圍欄外。
為了方便查詢和維護(hù),我們還可以使用其他技術(shù)來優(yōu)化我們的方案。例如,可以使用周邊搜索服務(wù)來快速查詢某個(gè)位置點(diǎn)周圍的圍欄。我們可以將所有的圍欄邊界存儲(chǔ)到一個(gè)搜索引擎中,當(dāng)需要查詢某個(gè)位置點(diǎn)周圍的圍欄時(shí),只需要將這個(gè)位置點(diǎn)作為查詢條件提交到搜索引擎即可。
以上就是我們的電子圍欄的延伸方案,該方案可以支持更多類型的圍欄形狀和更靈活的查詢方式,具有很高的效率和可拓展性。在實(shí)際應(yīng)用中,該方案可以應(yīng)用到車輛定位、電子地圖、移動(dòng)社交等領(lǐng)域。如果您對(duì)該方案感興趣,可以參考下面的代碼實(shí)現(xiàn)進(jìn)行嘗試。
代碼實(shí)現(xiàn)
以下是我們的代碼實(shí)現(xiàn),我們使用了Node.js和Redis來實(shí)現(xiàn)電子圍欄的延伸服務(wù):
VAR redis = require('redis');
var geohash = require('ngeohash');
var async = require('async');
var turf = require('@turf/turf');
var elasticsearch = require('elasticsearch');
// 初始化redis連接
var client = redis.createClient({
host: '127.0.0.1',
port: '6379'
});
// 初始化elasticsearch連接
var esClient = new elasticsearch.Client({
host: '127.0.0.1:9200',
log: 'trace'
});
// 圍欄類型
var FENCE_TYPE = {
POLYGON: 'polygon',
LINESTRING: 'linestring'
}
/**
* 創(chuàng)建圍欄
* @param {*} fenceId 圍欄ID
* @param {*} fenceType 圍欄類型
* @param {*} coords 圍欄坐標(biāo)點(diǎn)
* @param {*} callback 回調(diào)函數(shù)
*/
function createFence(fenceId, fenceType, coords, callback) {
// 構(gòu)建圍欄對(duì)象
var fence = {
type: fenceType,
coords: coords
};
// 將圍欄對(duì)象序列化為json字符串
var fenceStr = JSON.stringify(fence);
// 存儲(chǔ)圍欄對(duì)象
client.set(fenceId, fenceStr, function(ERR, reply) {
callback(err);
});
}
/**
* 刪除圍欄
* @param {*} fenceId 圍欄ID
* @param {*} callback 回調(diào)函數(shù)
*/
function deleteFence(fenceId, callback) {
// 刪除圍欄對(duì)象
client.del(fenceId, function(err, reply) {
callback(err);
});
}
/**
* 查詢圍欄
* @param {*} fenceId 圍欄ID
* @param {*} callback 回調(diào)函數(shù)
*/
function queryFence(fenceId, callback) {
// 查詢圍欄對(duì)象
client.get(fenceId, function(err, reply) {
if (err) {
return callback(err);
}
// 解析圍欄對(duì)象
var fence = JSON.parse(reply.toString());
// 查詢圍欄邊界中的所有點(diǎn)
var coords = fence.coords;
// 將邊界點(diǎn)解析為GeoHash值
var geoHashValues = coords.map(function(coord) {
var geoHash = geohash.encode(coord[1], coord[0], 6);
return geoHash;
});
// 查詢對(duì)應(yīng)的bitmap
var bitmapKeys = geoHashValues.map(function(geoHash) {
return 'fence_bitmap:' + geoHash;
});
client.bitcount(bitmapKeys, function(err, count) {
if (err) {
return callback(err);
}
var isInside = (count % 2 == 1); // 奇數(shù)個(gè)點(diǎn)在多邊形內(nèi)部,偶數(shù)個(gè)點(diǎn)在多邊形外部
callback(null, isInside);
});
});
}
/**
* 查詢某個(gè)點(diǎn)周圍的圍欄
* @param {*} lat 緯度
* @param {*} lng 經(jīng)度
* @param {*} radius 搜索范圍(千米)
* @param {*} callback 回調(diào)函數(shù)
*/
function queryNearbyFences(lat, lng, radius, callback) {
// 周邊搜索配置
var searchParams = {
index: 'fences',
type: 'fence',
body: {
query: {
bool: {
must: {
match_all: {}
},
filter: {
geo_distance: {
distance: radius + 'km',
location: {
lat: lat,
lon: lng
}
}
}
}
}
}
};
// 進(jìn)行搜索
esClient.search(searchParams, function(err, response) {
if (err) {
return callback(err);
}
var fences = response.hits.hits.map(function(hit) {
return hit._source;
});
callback(null, fences);
});
}
/**
* 初始化搜索引擎
*/
function initSearchEngine() {
// 創(chuàng)建索引
esClient.indices.create({
index: 'fences'
}, function(err, resp, status) {
if (err) {
console.log(err);
} else {
console.log("Index created!", resp);
}
});
// 映射類型和字段
var mapping = {
fence: {
properties: {
location: {
type: "geo_point"
}
}
}
};
// 更新映射
esClient.indices.putMapping({
index: "fences",
成都服務(wù)器托管選創(chuàng)新互聯(lián),先上架開通再付費(fèi)。
創(chuàng)新互聯(lián)(www.cdcxhl.com)專業(yè)-網(wǎng)站建設(shè),軟件開發(fā)老牌服務(wù)商!微信小程序開發(fā),APP開發(fā),網(wǎng)站制作,網(wǎng)站營銷推廣服務(wù)眾多企業(yè)。電話:028-86922220
當(dāng)前題目:突破界限Redis電子圍欄的延伸(redis電子圍欄范圍)
本文地址:http://www.dlmjj.cn/article/dpjpdsj.html


咨詢
建站咨詢
