diff --git a/AreaCityQuery.java b/AreaCityQuery.java index 9775f15..cd3105c 100644 --- a/AreaCityQuery.java +++ b/AreaCityQuery.java @@ -72,6 +72,7 @@ public class AreaCityQuery { * @param res 可以为null,如果提供结果对象,可通过此对象的Set_XXX属性控制某些查询行为,比如设置Set_ReturnWKTKey可以额外返回边界的WKT文本数据;并且本次查询的结果和统计数据将累加到这个结果内(性能测试用)。注意:此结果对象非线程安全 */ static public QueryResult QueryPoint(double lng, double lat, Func where, QueryResult res) throws Exception{ + CheckInitIsOK(); return QueryGeometry(Factory.createPoint(new Coordinate(lng, lat)), where, res); } @@ -87,12 +88,7 @@ static public QueryResult QueryPoint(double lng, double lat, Func where, QueryResult res) throws Exception{ - if(GetInitStatus()==3) { - throw new Exception(InitInfo.ErrMsg); - } - if(GetInitStatus()!=2) { - throw new Exception("需要先Init完成后,再来进行查询调用"); - } + CheckInitIsOK(); if(res==null) res=new QueryResult(); res.QueryCount++; long t_Start=System.nanoTime(); @@ -207,12 +203,7 @@ static public QueryResult QueryGeometry(Geometry geom, Func wher * @param onFind 可选提供一个回调函数,每次查询到一条wkt数据后会通过onFind回传,String[]参数为[prop,wkt];如果返回false数据将不会存入res结果中(也会忽略wktKey参数),需在回调中自行处理数据 */ static public QueryResult ReadWKT_FromWkbsFile(String wktKey, QueryResult res, Func where, Func onFind) throws Exception{ - if(GetInitStatus()==3) { - throw new Exception(InitInfo.ErrMsg); - } - if(GetInitStatus()!=2) { - throw new Exception("需要先Init完成后,再来进行查询调用"); - } + CheckInitIsOK(); if(res==null) res=new QueryResult(); res.QueryCount++; long t_Start=System.nanoTime(); @@ -296,12 +287,7 @@ static public QueryResult ReadWKT_FromWkbsFile(String wktKey, QueryResult res, F * @param onFind 可选提供一个回调函数,每次查询到一条wkt数据后会通过onFind回传,String[]参数为[prop,wkt];如果返回false数据将不会存入res结果中(也会忽略wktKey参数),需在回调中自行处理数据 */ static public QueryResult Debug_ReadGeometryGridSplitsWKT(String wktKey, QueryResult res, Func where, Func onFind) throws Exception { - if(GetInitStatus()==3) { - throw new Exception(InitInfo.ErrMsg); - } - if(GetInitStatus()!=2) { - throw new Exception("需要先Init完成后,再来进行查询调用"); - } + CheckInitIsOK(); if(res==null) res=new QueryResult(); res.QueryCount++; long t_Start=System.nanoTime(); @@ -451,6 +437,15 @@ static public void Init_StoreInWkbsFile(String dataFilePath, String saveWkbsFile static public int GetInitStatus() { return InitLock[0]; } + /** 检查init状态是否是2已初始化完成,未完成会抛出错误原因 **/ + static public void CheckInitIsOK() throws Exception { + if(InitLock[0]==3) { + throw new Exception(InitInfo.ErrMsg); + } + if(InitLock[0]!=2) { + throw new Exception("需要先Init完成后,再来进行查询调用"); + } + } /** 将init状态设置为0(未初始化),允许重新Init **/ static public void ResetInitStatus() { synchronized (InitLock) { @@ -660,7 +655,8 @@ public String Exec(Object val) throws Exception { } if(!IsStart[0]){ //等待开始标志 - if(line.indexOf("\"features\"")==0){ + int fIdx=line.indexOf("\"features\""); + if(fIdx==0 || fIdx>0 && fIdx>=line.length()-14){ if(!line.endsWith("[")){ throw new Exception("初始化传入的文件第"+lineNo+"行风格不对,不支持处理此文件"); } @@ -1077,7 +1073,7 @@ static private byte[] ReadWkbFromFile(int pos) throws Exception { /** 通用回调接口 **/ - interface Func { oT Exec(iT val) throws Exception; } + public interface Func { oT Exec(iT val) throws Exception; } diff --git a/README.md b/README.md index 147352f..438be1e 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ System.out.println(AreaCityQuery.GetInitInfo().toString()); //打印初始化详 QueryResult res1=AreaCityQuery.QueryPoint(114.044346, 22.691963, null, null); //查询和一个图形(点、线、面)有交点的所有边界图形的属性数据,可通过res参数让查询额外返回wkt格式边界数据 -Geometry geom=new WKTReader(AreaCityQuery.Factory).read("LINESTRING(114.233963 30.546038, 114.468109 30.544264)"); +Geometry geom=new WKTReader(AreaCityQuery.Factory).read("LINESTRING(114.30115 30.57962, 117.254285 31.824198, 118.785633 32.064869)"); QueryResult res2=AreaCityQuery.QueryGeometry(geom, null, null); //读取省市区的边界数据wkt格式,这个例子会筛选出武汉市所有区县 @@ -131,7 +131,7 @@ System.out.println(res1+"\n"+res2+"\n"+res3+"\n"+res4); - 使用多个不同类名:同一个包下,将`AreaCityQuery.java`改名成不同的类,比如:`com.aa.AreaCityQuery1`、`com.aa.AreaCityQuery2`,这样就可以通过`AreaCityQuery1`、`AreaCityQuery2`类分别进行初始化,多个实例互不干扰。 ### 附:关于Java程序打包发布 -本程序只支持从文件路径进行初始化,所以请将数据文件放到一个磁盘目录内,不要打包进jar中;如果是docker发布,可以在dockerfile中将数据文件copy进docker镜像内的目录中。 +本程序只支持从文件路径进行初始化,所以请将数据文件放到一个磁盘目录内,不要打包进jar中;如果是docker发布,可以在dockerfile中用VOLUME映射宿主机目录、或直接将数据文件copy进docker镜像内的目录中。 [​](?) diff --git a/Test.java b/Test.java index 537575b..b9c9fa4 100644 --- a/Test.java +++ b/Test.java @@ -43,7 +43,7 @@ static public void main(String[] args) throws Exception { QueryResult res1=AreaCityQuery.QueryPoint(114.044346, 22.691963, null, null); //查询和一个图形(点、线、面)有交点的所有边界图形的属性数据,可通过res参数让查询额外返回wkt格式边界数据 - Geometry geom=new WKTReader(AreaCityQuery.Factory).read("LINESTRING(114.233963 30.546038, 114.468109 30.544264)"); + Geometry geom=new WKTReader(AreaCityQuery.Factory).read("LINESTRING(114.30115 30.57962, 117.254285 31.824198, 118.785633 32.064869)"); QueryResult res2=AreaCityQuery.QueryGeometry(geom, null, null); //读取省市区的边界数据wkt格式,这个例子会筛选出武汉市所有区县 @@ -555,6 +555,38 @@ static void Query_Point() throws Exception { } } + static void Query_Geometry() throws Exception { + System.out.println("========== 查询和任意一个几何图形相交的省市区乡镇数据 =========="); + System.out.println("注意:输入WKT的坐标系必须和初始化时使用的geojson数据的坐标系一致,否则坐标可能会有比较大的偏移,导致查询结果不正确。"); + System.out.println("请输入一个WKT文本(Well Known Text):"); + System.out.println(" - 比如:POINT(114.044346 22.691963),坐标点,为广东省 深圳市 龙华区"); + System.out.println(" - 比如:LINESTRING(114.30115 30.57962, 117.254285 31.824198, 118.785633 32.064869),路径线段,武汉-合肥-南京 三个点连成的线段"); + System.out.println(" - 比如:POLYGON((113.305514 30.564249, 113.305514 32.881526, 117.326510 32.881526, 117.326510 30.564249, 113.305514 30.564249)),范围,湖北-河南-安徽 三省交界的一个超大矩形范围"); + System.out.println(" - 输入 exit 退出查询"); + while(true){ + System.out.print("> "); + String inStr=ReadIn().trim(); + if(inStr.length()==0) { + System.out.println("输入为空,请重新输入!如需退出请输入exit"); + continue; + } + if(inStr.equals("exit")) { + System.out.println("bye! 已退出查询。"); + System.out.println(); + return; + } + Geometry geom; + try { + geom=new WKTReader(AreaCityQuery.Factory).read(inStr); + }catch(Exception e) { + System.out.println("输入的WKT解析失败:"+e.getMessage()); + continue; + } + QueryResult res=AreaCityQuery.QueryGeometry(geom, null, null); + System.out.println(res.toString()); + } + } + static void Read_WKT() throws Exception { System.out.println("========== 读取省市区乡镇边界的WKT文本数据 =========="); System.out.println("遍历所有边界图形的属性列表查询出符合条件的属性,然后返回图形的属性+边界图形WKT文本。 "); @@ -772,6 +804,7 @@ static void Start(String[] args) throws Exception { System.out.println("5. 测试:多线程性能测试"); System.out.println(HR); System.out.println("6. 查询: QueryPoint 查找坐标点所在省市区乡镇"); + System.out.println("A. 查询: QueryGeometry 查找和图形相交的省市区乡镇"); System.out.println("7. 查询: ReadWKT 读取省市区乡镇边界的WKT文本数据"); System.out.println("8. 查询: Debug 读取边界网格划分图形WKT文本数据"); System.out.println(HR); @@ -788,7 +821,7 @@ static void Start(String[] args) throws Exception { while(true) { int byt=System.in.read(); inTxt+=(char)byt; - inTxt=inTxt.trim(); + inTxt=inTxt.trim().toUpperCase(); if(byt!='\n') { continue; @@ -812,6 +845,9 @@ static void Start(String[] args) throws Exception { } else if(isInit && inTxt.equals("6")) { Query_Point(); waitAnyKey=false; + } else if(isInit && inTxt.equals("A")) { + Query_Geometry(); + waitAnyKey=false; } else if(isInit && inTxt.equals("7")) { Read_WKT(); waitAnyKey=false; @@ -822,7 +858,7 @@ static void Start(String[] args) throws Exception { if(StartHttpApiServer()) { waitAnyKey=false; } - } else if(inTxt.equals("exit")) { + } else if(inTxt.equals("EXIT")) { System.out.println("bye!"); return; } else {