本文介紹通過Tair(企業版)的GIS結構,實現同城購業務。
背景說明
隨著同城購業務的興起,品牌商家在其眾多門店中判斷出距離消費者最近門店的情境越來越流行。
商家通常會對每一個門店設定可銷售的範圍,可能是以行政區劃分,也可能是不規則形狀的地區,或按照半徑圈選。如果消費者座標在銷售範圍內,就認為該門店可以對該消費者進行銷售,否則,則不可銷售。此模型為:判斷點(消費者)和多邊形(門店銷售範圍)是否為內含項目關聯性。
該方案的傳統架構通常使用MySQL或PostGIS資料庫,雖然其對GIS相關能力有專業的支援,API也比較完備,但是由於MySQL或PostGis資料庫本身磁碟儲存的特性,查詢速度較慢,特別是在資料量較大的情境下,會產生多次磁碟讀IO,容易導致業務查詢逾時。
您可以使用TairGIS能力構建新一代判店系統,TairGIS底層使用RTree結構,支援常見的Contains、Within、Intersects等關係判斷,可以在毫秒(ms)層級返回查詢結果。更多資訊請參見GIS。
方案概述
將某品牌旗下各門店的銷售範圍存入GIS中。
根據消費者GPS座標,查詢可進行銷售服務的門店。
程式碼範例
本樣本的Python版本為3.8,且已安裝Tair-py依賴,Tair-py的快捷安裝命令為:pip3 install tair
。
# -*- coding: utf-8 -*-
# !/usr/bin/env python
from typing import Dict
from tair import Tair
from tair import ResponseError
def get_tair() -> Tair:
"""
該方法用於串連Tair執行個體。
* host:Tair執行個體串連地址。
* port:Tair執行個體的連接埠號碼,預設為6379。
* password:Tair執行個體的密碼(預設帳號)。若通過自訂帳號串連,則密碼格式為“username:password”。
"""
tair: Tair = Tair(
host="r-8vb************.redis.zhangbei.rds.aliyuncs.com",
port=6379,
db=0,
password="D******23",
decode_responses=True
)
return tair
def add_brand_store(brandID: str, mapping: Dict[str, str]) -> bool:
"""
該方法為通過GIS.ADD命令,將品牌(brandID)下的各門店(storeID)與其銷售範圍(store_wkt)存入GIS中。
"""
try:
tair = get_tair()
ret = tair.gis_add(brandID, mapping)
return ret == 1
except ResponseError as e:
print(e)
return False
def get_brand_all(brandID):
"""
該方法為通過GIS.GETALL命令,擷取某品牌的全部門店及其對應銷售範圍。
"""
try:
tair = get_tair()
return tair.gis_getall(brandID)
except:
return None
def get_service_store(brandID: str, user_location: str):
"""
根據消費者座標(user_location),查詢可進行銷售服務的門店。
"""
try:
tair = get_tair()
return tair.gis_contains(brandID, user_location)
except:
return None
if __name__ == "__main__":
tair = get_tair()
# 添加“brand1”品牌的2家門店銷售範圍。
add_brand_store(
"brand1",
{
"store_1": "POLYGON ((120.14772 30.19513, 120.15370 30.17838, 120.19385 30.18011, 120.18853 30.20817))",
"store_2": "POLYGON ((120.18986 30.20852, 120.19651 30.17988, 120.22512 30.17978, 120.21667 30.22292))"
},
)
print("查詢“brand1”品牌的所有門店及銷售範圍:")
print(get_brand_all('brand1'))
print("查詢可對消費者(120.19707 30.19539)進行銷售服務的門店資訊:")
print(get_service_store('brand1', 'POINT(120.19707 30.19539)'))
本樣本的正確執行結果如下:
查詢“brand1”品牌的所有門店及銷售範圍:
['store_1', 'POLYGON((120.14772 30.19513,120.1537 30.17838,120.19385 30.18011,120.18853 30.20817))', 'store_2', 'POLYGON((120.18986 30.20852,120.19651 30.17988,120.22512 30.17978,120.21667 30.22292))']
查詢可對消費者(120.19707 30.19539)進行銷售服務的門店資訊:
[1, ['store_2', 'POLYGON((120.18986 30.20852,120.19651 30.17988,120.22512 30.17978,120.21667 30.22292))']]
結果說明:消費者(120.19707 30.19539)的可服務門店為store_2
。
總結
同城購、買菜、本地商超等應用均可通過TairGIS資料結構,方便地實現地理相關的計算,同時也能滿足使用者對高效能的需求。