lucene geohash 在外卖场景中,商家不规则多边形配送范围技术应用
一、場景描述? ?
? ?當我們在定外賣的時候,系統是如何根據我們的位置搜到附近商家,當商家的配送范圍是不規則的時候,系統是如何處理。
?二、 理論基礎
1.?GeoHash特點
1)GeoHash用一個字符串表示經度和緯度兩個坐標,比如我現在所在位置的GeoHash值為 wx4sv61q;
2)GeoHash標識的并不是一個點,而是一個區域,比如 wx4sv61q 對應的就是一個矩形區域;
3)編碼的前綴可以標識更大的區域,比如 wx4sv61 編碼代表的區域要大于 wx4sv61q 代表的區域,但是 wx4sv61q 代表的區域一定在 wx4sv61 代表的區域內。
? ? ? 因此我們再去做距離檢索的時候,只需要對GeoHash進行前綴匹配即可
2.GeoHash原理
? GeoHash最簡單的解釋就是將一個位置信息轉化成一個可以排序、可以比較的字符串編碼
? ? ? 具體的實現大家可以自行百度
? 3.如何證明點在面里? ? ??
A.夾角和判別法:判斷目標點與所有邊的夾角和是否為360度,為360度則在多邊形內部。
B.引射線法:從目標點出發引一條射線,看這條射線和多邊形所有邊的交點數目。如果有奇數個交點,則說明在內部,如果有偶數個交點,則說明在外部。
具體做法:將測試點的Y坐標與多邊形的每一個點進行比較,會得到一個測試點所在的行與多邊形邊的交點的列表。在下圖的這個例子中有8條邊與測試點所在的行相交,而有6條邊沒有相交。如果測試點的兩邊點的個數都是奇數個則該測試點在多邊形內,否則在多邊形外。在這個例子中測試點的左邊有5個交點,右邊有三個交點,它們都是奇數,所以點在多邊形內。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
C. java.awt.geom.GeneralPath? jdk自帶畫圖工具,相對來說比較簡單三、實習方式
? ? ? ?1.用? lucene GeoHash 在索引中 統計出用戶? 10公里范圍內的商家
? ? ? ? 2. 計算此用戶是否在每個商家的配送范圍內。(證明二維空間里? 點是否面里)
四、代碼實現
pom.xml? 所需的maven依賴配置
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><lib.lucene.version>6.1.0</lib.lucene.version></properties><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.1</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>${lib.lucene.version}</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-common</artifactId><version>${lib.lucene.version}</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-spatial</artifactId><version>${lib.lucene.version}</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-spatial-extras</artifactId><version>${lib.lucene.version}</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-smartcn</artifactId><version>${lib.lucene.version}</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.9</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.0.2</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-client</artifactId><version>4.0.0</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion><exclusion><artifactId>zookeeper</artifactId><groupId>org.apache.zookeeper</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.6</version></dependency><dependency><groupId>com.101tec</groupId><artifactId>zkclient</artifactId><version>0.10</version><exclusions><exclusion><artifactId>zookeeper</artifactId><groupId>org.apache.zookeeper</groupId></exclusion></exclusions></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.5.3</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-core-asl</artifactId><version>1.9.13</version></dependency></dependencies>代碼實現
package com.people.lucene;/*** Created by Administrator on 2018/1/4.*/ import java.awt.geom.Point2D; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List;import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.spatial.SpatialStrategy; import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy; import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree; import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree; import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory;import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.distance.DistanceUtils; import org.locationtech.spatial4j.shape.Point; import org.locationtech.spatial4j.shape.Shape;import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper;/*** Lucene spatial演示**/ public class SpatialExample {public static void main(String[] args) {init();try {indexPoints();search();}catch (Exception e){e.printStackTrace();}}public void test() throws Exception {}/** Spatial4j上下文 */private static SpatialContext ctx;// "ctx" is the conventional variable name/** 提供索引和查詢模型的策略接口 */private static SpatialStrategy strategy;/** 索引目錄 */private static Directory directory;private static void init() {// SpatialContext也可以通過SpatialContextFactory工廠類來構建ctx = SpatialContext.GEO;//網格最大11層, geohash的精度int maxLevels = 11;//Spatial TiersSpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");directory = new RAMDirectory();}public static void indexPoints() throws Exception {IndexWriterConfig iwConfig = new IndexWriterConfig(new SmartChineseAnalyzer());IndexWriter indexWriter = new IndexWriter(directory, iwConfig);JsonFactory jsonFactory = new JsonFactory();jsonFactory.enable(JsonParser.Feature.ALLOW_COMMENTS);ObjectMapper mapper = new ObjectMapper(jsonFactory);BufferedReader br = new BufferedReader(new InputStreamReader(SpatialExample.class.getClassLoader().getResourceAsStream("shop.json")));String line = null;while ((line = br.readLine()) != null) {ShopBean shopBean = mapper.readValue(line, ShopBean.class);//這里的x,y即經緯度,x為Longitude(經度),y為Latitude(緯度)Document document = newSampleDocument(shopBean.getId(), shopBean.getName(),shopBean.getShape() ,ctx.makePoint(shopBean.getLongitude(), shopBean.getLatitude()));indexWriter.addDocument(document);}indexWriter.close();}private static Document newSampleDocument(int id, String title, String shapeEnclosure ,Shape... shapes) {Document doc = new Document();doc.add(new StoredField("id", id));doc.add(new NumericDocValuesField("id", id));doc.add(new TextField("name", title, Store.YES));doc.add(new TextField("shape", shapeEnclosure, Store.YES));// Potentially more than one shape in this field is supported by some// strategies; see the javadocs of the SpatialStrategy impl to see.for (Shape shape : shapes) {for (Field f : strategy.createIndexableFields(shape)) {doc.add(f);}// store it too; the format is up to you// (assume point in this example)Point pt = (Point) shape;doc.add(new StoredField(strategy.getFieldName(), pt.getX() + " " + pt.getY()));}return doc;}public static void search() throws Exception {searchInner("密室");System.out.println("----------------");//searchInner("咖啡");}private static void searchInner(String keyword) throws Exception {IndexReader indexReader = DirectoryReader.open(directory);IndexSearcher indexSearcher = new IndexSearcher(indexReader);// --Filter by circle (<= distance from a point)// Search with circle// note: SpatialArgs can be parsed from a string//Point pt = ctx.makePoint(121.41791, 31.21867);Point pt = ctx.makePoint(116.45845, 39.983086);// the distance in kmValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);//按距離由近及遠排序Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher); // false=asc distSpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,ctx.makeCircle(pt, DistanceUtils.dist2Degrees(3.0, DistanceUtils.EARTH_MEAN_RADIUS_KM)));Query query = strategy.makeQuery(args);BooleanQuery.Builder bqb = new BooleanQuery.Builder();bqb.add(query, BooleanClause.Occur.MUST);bqb.add(new TermQuery(new Term("name", keyword)), BooleanClause.Occur.MUST);TopDocs docs = indexSearcher.search(bqb.build(), 20, distSort);printDocs(indexSearcher, docs, args);indexReader.close();}private static void printDocs(IndexSearcher indexSearcher, TopDocs docs, SpatialArgs args) throws IOException {for (int i = 0; i < docs.totalHits; i++) {Document doc = indexSearcher.doc(docs.scoreDocs[i].doc);//判斷是否在商家配送范圍內if(null !=doc.getField("shape").stringValue()){PageData orderLocation = new PageData();orderLocation.setX( "116.45845");orderLocation.setY( "39.983086");// 商業區域(百度多邊形區域經緯度集合)boolean isInclude = isInPolygon(orderLocation, doc.getField("shape").stringValue());//如果不在范圍內,不做展示if(!isInclude){continue;}}System.out.print(doc.getField("id").numericValue().intValue());System.out.print(":" + doc.getField("name").stringValue());//計算距離String docStr = doc.getField(strategy.getFieldName()).stringValue();// assume docStr is "x y" as written in newSampleDocument()int spaceIdx = docStr.indexOf(' ');double x = Double.parseDouble(docStr.substring(0, spaceIdx));double y = Double.parseDouble(docStr.substring(spaceIdx + 1));double docDistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);System.out.print("(" + DistanceUtils.degrees2Dist(docDistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM) + "km)");System.out.println();}}/*** 判斷當前位置是否在多邊形區域內* @param orderLocation 當前點* @param partitionLocation 區域頂點* @return*/public static boolean isInPolygon(PageData orderLocation,String partitionLocation){double p_x =Double.parseDouble(orderLocation.getX());double p_y =Double.parseDouble(orderLocation.getY());Point2D.Double point = new Point2D.Double(p_x, p_y);List<Point2D.Double> pointList= new ArrayList<Point2D.Double>();String[] strList = partitionLocation.split(",");for (String str : strList){String[] points = str.split("_");double polygonPoint_x=Double.parseDouble(points[1]);double polygonPoint_y=Double.parseDouble(points[0]);Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y);pointList.add(polygonPoint);}//return IsPtInPoly(point,pointList); // truereturn checkWithJdkGeneralPath(point,pointList); // true}/*** 返回一個點是否在一個多邊形區域內, 如果點位于多邊形的頂點或邊上,不算做點在多邊形內,返回false* @param point* @param polygon* @return*/public static boolean checkWithJdkGeneralPath(Point2D.Double point, List<Point2D.Double> polygon) {java.awt.geom.GeneralPath p = new java.awt.geom.GeneralPath();Point2D.Double first = polygon.get(0);p.moveTo(first.x, first.y);polygon.remove(0);for (Point2D.Double d : polygon) {p.lineTo(d.x, d.y);}p.lineTo(first.x, first.y);p.closePath();return p.contains(point);}/*** 判斷點是否在多邊形內,如果點位于多邊形的頂點或邊上,也算做點在多邊形內,直接返回true* @param point 檢測點* @param pts 多邊形的頂點* @return 點在多邊形內返回true,否則返回false*/public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){int N = pts.size();boolean boundOrVertex = true; //如果點位于多邊形的頂點或邊上,也算做點在多邊形內,直接返回trueint intersectCount = 0;//cross points count of xdouble precision = 2e-10; //浮點類型計算時候與0比較時候的容差Point2D.Double p1, p2;//neighbour bound verticesPoint2D.Double p = point; //當前點p1 = pts.get(0);//left vertexfor(int i = 1; i <= N; ++i){//check all raysif(p.equals(p1)){return boundOrVertex;//p is an vertex}p2 = pts.get(i % N);//right vertexif(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interestsp1 = p2;continue;//next ray left point}if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of)if(p.y <= Math.max(p1.y, p2.y)){//x is before of rayif(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal rayreturn boundOrVertex;}if(p1.y == p2.y){//ray is verticalif(p1.y == p.y){//overlies on a vertical rayreturn boundOrVertex;}else{//before ray++intersectCount;}}else{//cross point on the left sidedouble xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of yif(Math.abs(p.y - xinters) < precision){//overlies on a rayreturn boundOrVertex;}if(p.y < xinters){//before ray++intersectCount;}}}}else{//special case when ray is crossing through the vertexif(p.x == p2.x && p.y <= p2.y){//p crossing over p2Point2D.Double p3 = pts.get((i+1) % N); //next vertexif(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x++intersectCount;}else{intersectCount += 2;}}}p1 = p2;//next ray left point}if(intersectCount % 2 == 0){//偶數在多邊形外return false;} else { //奇數在多邊形內return true;}}static class PageData {private String X ;private String Y ;public String getX() {return X;}public void setX(String x) {X = x;}public String getY() {return Y;}public void setY(String y) {Y = y;}}} ShopBean 實體類package com.people.lucene;/*** Created by Administrator on 2018/1/4.*/ public class ShopBean {private int id;private String name;private double longitude;private double latitude;private String address;private String shape;public String getShape() {return shape;}public void setShape(String shape) {this.shape = shape;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getLongitude() {return longitude;}public void setLongitude(double longitude) {this.longitude = longitude;}public double getLatitude() {return latitude;}public void setLatitude(double latitude) {this.latitude = latitude;} } shop.jon 數據 {"id":22130906,"name":"小仙屋劇情密室逃脫","address":"浙江南路78號東新大廈216室","longitude":116.45845,"latitude":39.983086,"shape":"39.985962_116.456579,39.983032_116.452663,39.980931_116.453345,39.979853_116.45604,39.979632_116.462005,39.985023_116.465095"} {"id":22130905,"name":"nook諾克密室&DIY多肉(人民廣場店)","address":"浙江南路78號東新大廈216室","longitude":121.48206,"latitude":31.2288,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":2871847,"name":"星巴克(江蘇店)","address":"江蘇路458號1層116","longitude":121.43091,"latitude":31.218975,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":18179096,"name":"極道真人密室逃脫(人民廣場大世界總店)","address":"金陵東路569號匯通大廈804室","longitude":121.48103,"latitude":31.226982,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":22676436,"name":"I high club","address":"上大路99號","longitude":121.39542,"latitude":31.312284,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":16820366,"name":"小仙屋劇情密室逃脫","address":"膠州路941號長久商務中心2203室","longitude":121.436646,"latitude":31.237585,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":8852374,"name":"魔方劇情真人密室逃脫(靜安店)","address":"西康路618號華通大廈13樓D座","longitude":121.446335,"latitude":31.23506,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":24065790,"name":"A9真人密室逃脫(黃浦店)","address":"福州路465號上海書城6樓貝亦迪科技體驗館","longitude":121.48146,"latitude":31.23335,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":66552930,"name":"Charles' VR 虛擬現實體驗館","address":"五角場大學路161號701室","longitude":121.509865,"latitude":31.304022,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":8843152,"name":"iDream真人密室逃脫(百米香榭店)","address":"浙江路229號百米香榭街354店鋪","longitude":121.479,"latitude":31.233591,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":11579304,"name":"1617Cafe(中山公園龍之夢服務區)","address":"長寧路890號玫瑰坊1樓88B","longitude":121.41786,"latitude":31.219374,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":19649586,"name":"MC精品真人密室逃脫(八佰伴店)","address":"浦東南路1088號4F-05","longitude":121.515366,"latitude":31.228285,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":66350697,"name":"初魚vr咖-虛擬現實體驗館","address":"大學路103號802室","longitude":121.51079,"latitude":31.304335,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":3564328,"name":"Boom Cafe","address":"宣化路313號","longitude":121.42288,"latitude":31.216875,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":6850935,"name":"nook諾克密室逃脫(長寧店)","address":"中山公園附近","longitude":121.4217,"latitude":31.215496,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23306435,"name":"暗黑魔盒集中營(鬼屋密室)","address":"翔殷路1099號4樓","longitude":121.51839,"latitude":31.30048,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":6438722,"name":"Min魔魔島密室逃脫(中山公園店)","address":"長寧路988號花園大廈6樓606室","longitude":121.417885,"latitude":31.21871,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":5411446,"name":"COSTA COFFEE(上海長寧新世界)","address":"長寧路823號1樓","longitude":121.42047,"latitude":31.21866,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":7658577,"name":"因奧密室","address":"錦秋路699弄二區一排121號","longitude":121.38976,"latitude":31.32106,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":17163949,"name":"aMaze真人密室逃脫","address":"長寧路988號花園大廈903","longitude":121.41791,"latitude":31.21867,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":21930982,"name":"MANGOSIX(長寧龍之夢店)","address":"長寧路1018號龍之夢購物中心1樓1075號鋪","longitude":121.41745,"latitude":31.21966,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":13915001,"name":"ZOOCOFFEE(定西路店)","address":"定西路1100號遼油大廈101室","longitude":121.42346,"latitude":31.2117,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":8019669,"name":"貝克街5號密室逃脫","address":"長壽路181弄日月星辰2號樓1007室","longitude":121.4421,"latitude":31.241724,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":67979580,"name":"Zero VR零維虛擬現實體驗館","address":"定西路1310弄18號303","longitude":121.42359,"latitude":31.215818,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":21374196,"name":"Dobe密室逃脫(楊浦大學路店)","address":"大學路33號701室loft37運動酒吧樓上","longitude":121.5117,"latitude":31.3047,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":17999648,"name":"DTR夢空間密室逃脫(八佰伴店)","address":"張楊路628弄東明廣場2號樓2203室","longitude":121.52058,"latitude":31.228123,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":22636011,"name":"貓小姐的店","address":"長寧路890號玫瑰坊1樓","longitude":121.41781,"latitude":31.219257,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23516373,"name":"Forest Rose Afternoon Tea","address":"長寧路890號玫瑰坊1F-72","longitude":121.418724,"latitude":31.21922,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23550163,"name":"白兔子密室逃脫","address":"長寧路405弄1號地下1層","longitude":121.427055,"latitude":31.22307,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":32392280,"name":"海盜奇兵密室逃脫(五角場店)","address":"大學路33號601室loft37運動酒吧樓上","longitude":121.511765,"latitude":31.304789,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":56588006,"name":"第五空間咖啡館","address":"長寧路1018號龍之夢購物中心4樓4202","longitude":121.41633,"latitude":31.218613,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":32508745,"name":"Vital Tea(長寧龍之夢店)","address":"長寧路1018號龍之夢購物中心1F-1055","longitude":121.41703,"latitude":31.21874,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":58805309,"name":"探險者世界(VR體驗館)","address":"人民廣場迪美購物中心B1層","longitude":121.47345,"latitude":31.228691,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":57380950,"name":"阿拉丁真人密室逃脫(八佰伴店)","address":"張楊路628弄東明廣場3號2C","longitude":121.52024,"latitude":31.22793,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":17950766,"name":"JOJO真人密室逃脫","address":"長壽路457號2樓C室","longitude":121.43657,"latitude":31.23879,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":57832242,"name":"Daisy花&咖啡","address":"江蘇路54弄18號后門","longitude":121.42814,"latitude":31.223377,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":28615799,"name":"Let it go臺球密室逃脫","address":"國濟路20號七樓","longitude":121.51599,"latitude":31.30196,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":38092929,"name":"趣密室 & DIY手工坊","address":"石門二路333弄3號振安廣場恒安大廈22樓E座","longitude":121.4598,"latitude":31.235432,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":57546152,"name":"好久不讀 long time no read","address":"愚園路1208號","longitude":121.42646,"latitude":31.219221,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":66865461,"name":"VR family-虛擬現實體驗館","address":"大學路錦創路20號1101室創智66商務樓內(一兆韋德健身館旁)","longitude":121.50922,"latitude":31.304209,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":9335488,"name":"77密室逃脫+真人CS(五角場店)","address":"四平路2500號東方商廈樓上金島大廈1305室","longitude":121.515465,"latitude":31.298822,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23062800,"name":"毛利偵探事務所密室逃脫","address":"大學路302號702室","longitude":121.50763,"latitude":31.30317,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":50431953,"name":"顛九宮真人游戲體驗館(楊浦店)","address":"國權路與邯鄲路交叉口","longitude":121.50096,"latitude":31.297478,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":14155399,"name":"慢時光MYTIMECAFE","address":"武夷路339號","longitude":121.42406,"latitude":31.21347,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":59180246,"name":"月球劇情密室逃脫(淮海中路店)","address":"普安路189號曙光大廈18D","longitude":121.47889,"latitude":31.22244,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":27174604,"name":"MC精品真人密室逃脫(五角場店)","address":"翔殷路1128號8樓B4、B5","longitude":121.51691,"latitude":31.30103,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":32640417,"name":"西塞密室(長寧店)","address":"愚園路1391號3樓","longitude":121.42288,"latitude":31.218843,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23403568,"name":"暗黑迷宮第三季","address":"南京西路1788號1788廣場F201","longitude":121.44376,"latitude":31.22278,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":7045554,"name":"巴黎春天新世界酒店濃咖啡","address":"定西路1555號酒店2樓","longitude":121.4211,"latitude":31.218554,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":24899623,"name":"GIVE ME FIVE劇情密室逃脫(大學路店)","address":"大學路錦創路26號1102室創智66商務樓內","longitude":121.50918,"latitude":31.30425,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":67335522,"name":"nook諾克劇情密室 & VR虛擬現實體驗館(五角場店)","address":"大學路錦創路26號1602室創智66商務樓內","longitude":121.509315,"latitude":31.304174,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":4275877,"name":"Home Garden","address":"安化路492號德必易園多媒體創意園區106室","longitude":121.4202,"latitude":31.215342,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":18593150,"name":"TIK TOK","address":"江蘇路458號112室舜元企業發展大廈","longitude":121.43106,"latitude":31.218548,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":22447664,"name":"Running基地","address":"軍工路100號","longitude":121.558266,"latitude":31.281694,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":24678174,"name":"太平洋咖啡(兆豐廣場店)","address":"長寧路999號兆豐廣場","longitude":121.41788,"latitude":31.21765,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":57439748,"name":"essence casa","address":"愚園路1329號","longitude":121.42449,"latitude":31.21873,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":65835399,"name":"大華虎城第三空間","address":"白麗路61號","longitude":121.35216,"latitude":31.27899,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":19671618,"name":"FullHouse桌游棋牌密室(南京西路店)","address":"大田路129號嘉發大廈A座25樓G","longitude":121.46391,"latitude":31.23294,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":23740568,"name":"aMaze真人密室逃脫(人民廣場大世界店)","address":"云南南路180號淮云大廈8樓","longitude":121.48128,"latitude":31.2265,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":22132387,"name":"智源咖啡(中山公園店)","address":"安化路492號易園","longitude":121.42034,"latitude":31.21529,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":56890263,"name":"跑男開始了 runningman(公司活動,年會撕名牌)","address":"淮海中路","longitude":121.49525,"latitude":31.22792,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":18636516,"name":"ASA亞撒真人密室逃脫","address":"武夷路418弄(近定西路)1號武定大廈203室","longitude":121.421974,"latitude":31.212627,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":5857955,"name":"Crazycube顛九宮密室逃脫(大學路店)","address":"創智坊大學路302號701室","longitude":121.50754,"latitude":31.303108,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":2036581,"name":"星巴克(龍之夢2店)","address":"長寧路1018號龍之夢購物中心1樓1073號鋪","longitude":121.416916,"latitude":31.218727,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":13913129,"name":"Captain.C真人密室逃脫","address":"延平路69號延平大廈701室","longitude":121.44161,"latitude":31.227833,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"} {"id":57682702,"name":"aMaze真人密室逃脫(五角場店)","address":"大學路292號602室","longitude":121.50777,"latitude":31.30327,"shape":"31.839064_117.219116,31.83253_117.219403,31.828511_117.218146,31.826763_117.219259,31.826118_117.220517,31.822713_117.23586,31.822958_117.238375,31.838512_117.23798,31.839617_117.226194,31.839586_117.222925"}
??
總結
以上是生活随笔為你收集整理的lucene geohash 在外卖场景中,商家不规则多边形配送范围技术应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python返回索引值_python 返
- 下一篇: 蛮力法求解凸包问题