- android端通過gps解析出所在的城市名,可以使用Geocoder來完成,但是Geocoder函數和android api的版本有關。2.1以上不能用
- 通過google map方式如:http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=true可以完成,也是比較簡單的一種形式,但是公司網關做了限制,不能訪問。
- 沒有辦法,只能通過gis解析城市名。
- 先來了解一下什么是gis:即地理信息系統(Geographic Information System),下面分點來介紹下所用到的開源的java GIS系統。
- 第一個用到的是Geotools,他是一個開源的Java GIS工具包,可利用它來開發符合標准的地理信息系統。Geotools提供了OGC(Open Geospatial Consortium)規范的一個實現來作為他們的開發。
- 第二個用到的是JTS,他是加拿大的 Vivid Solutions 做的一套開放源碼的 Java API。它提供了一套空間數據操作的核心算法,為在兼容OGC標准的空間對象模型中進行基礎的幾何操作提供2D空間謂詞API。提供一個資料鏈接:http://www.vividsolutions.com/jts/jtshome.htm
- 什么是shp文件:Shapefile文件是美國環境系統研究所(ESRI)所研制的GIS文件系統格式文件,是工業標准的矢量數據文件。 Shapefile將空間特征表中的非拓撲幾何對象和屬性信息存儲在數據集中,特征表中的幾何對象存為以坐標點集表示的圖形文件—SHP文件,Shapefile文件並不含拓撲(Topological)數據結構。一個Shape文件包括三個文件:一個主文件(*.shp),一個索引文件(*.shx),和一個dBASE(*.dbf)表。主文件是一個直接存取,變長度記錄的文件,其中每個記錄描述構成一個地理特征(Feature)的所有vertices坐標值。在索引文件中,每條記錄包含對應主文件記錄距離主文件頭開始的偏移量,dBASE表包含SHP文件中每一個Feature的特征屬性,表中幾何記錄和屬性數據之間的一一對應關系是基於記錄數目的ID。在dBASE文件中的屬性記錄必須和主文件中的記錄順序是相同的。圖形數據和屬性數據通過索引號建立一一對應的關系。相應的資料參考鏈接:http://blog.csdn.net/zapzqc/article/details/3123149
- 進入正題:通過shp文件 ,並返回一個集合。
1 // 讀取shp文件,返回所有文件信息 2 public static FeatureIterator<SimpleFeature> readSHP() 3 { 4 ShapefileDataStore shpDataStore = null; 5 long time1 = System.currentTimeMillis(); 6 try 7 { 8 // shp文件路徑 9 shpDataStore = new ShapefileDataStore(new File("E:\\geo\\geo\\region.shp").toURI().toURL()); 10 shpDataStore.setStringCharset(Charset.forName("GBK")); 11 // 文件名稱 12 String typeName = shpDataStore.getTypeNames()[0]; 13 FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null; 14 featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) shpDataStore.getFeatureSource(typeName); 15 FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures(); 16 itertor = result.features(); 17 } 18 catch (Exception e) 19 { 20 e.printStackTrace(); 21 } 22 System.out.println(System.currentTimeMillis() - time1 + "讀取shp文件時間"); 23 return itertor; 24 }
- 傳入經緯度信息解析出城市名。
1 // 根據個gps坐標獲取對應城市 2 public static String readInfo(String poingX, String pointY) 3 { 4 StringBuffer mBuffer = null; 5 String mCityName = ""; 6 try 7 { 8 if (null == itertor) 9 { 10 itertor = readSHP(); 11 } 12 mBuffer = new StringBuffer(); 13 // 迭代iterator 14 while (itertor.hasNext()) 15 { 16 SimpleFeature feature = itertor.next(); 17 Collection<Property> p = feature.getProperties(); 18 Iterator<Property> it = p.iterator(); 19 while (it.hasNext()) 20 { 21 String value = null; 22 Property pro = it.next(); 23 value = pro.getValue().toString(); 24 mBuffer.append(value + "\r\n"); 25 } 26 count++; 27 mList.add(mBuffer.toString()); 28 mBuffer.delete(0, mBuffer.length()); 29 } 30 itertor.close(); 31 String data = null; 32 String[] arr = null; 33 // 如果緩存mGpsBuffer為空,則從新到所有集合中循環。 34 if (null != mGpsBuffer) 35 { 36 WKTReader reader = new WKTReader(geometryFactory); 37 String point1 = "POINT(" + poingX + " " + pointY + ")"; 38 Point point = (Point) reader.read(point1); 39 MultiPolygon multiPolygon = (MultiPolygon) reader.read(mGpsBuffer[0]); 40 // 傳過來的gps經緯度坐標,為一個點 41 Geometry geometry1 = geometryFactory.createGeometry(point); 42 // 區域內所有點圍城的一個多邊形 43 Geometry geometry2 = geometryFactory.createGeometry(multiPolygon); 44 // 如果該點包含在多邊形里面則解析出城市名 45 if (geometry2.contains(geometry1)) 46 { 47 mCityName = mGpsBuffer[1]; 48 System.out.println("cityname1 = " + mGpsBuffer[1]); 49 return mCityName; 50 } 51 } 52 //循環所有點集合,判斷點是否在其中的多邊形里面。 53 for (int i = 0; i < mList.size(); i++) 54 { 55 data = mList.get(i); 56 arr = data.split("\r\n"); 57 try 58 { 59 mGpsBuffer = new String[arr.length]; 60 WKTReader reader = new WKTReader(geometryFactory); 61 String point1 = "POINT(" + poingX + " " + pointY + ")"; 62 Point point = (Point) reader.read(point1); 63 MultiPolygon multiPolygon = (MultiPolygon) reader.read(arr[0]); 64 Geometry geometry1 = geometryFactory.createGeometry(point); 65 Geometry geometry2 = geometryFactory.createGeometry(multiPolygon); 66 if (geometry2.contains(geometry1)) 67 { 68 mCityName = arr[1]; 69 //將多邊形的信息存入緩存中。 70 mGpsBuffer = arr; 71 System.out.println("cityname = " + arr[1]); 72 break; 73 } 74 } 75 catch (Exception e) 76 { 77 e.printStackTrace(); 78 } 79 } 80 } 81 catch (Exception e) 82 { 83 e.printStackTrace(); 84 // TODO: handle exception 85 } 86 return mCityName; 87 }
- 至此解析工作已完成。進過測試,解析速度還是可以的,如果再優化效率還會提升。