├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── appleyk │ ├── Application.java │ ├── entity │ └── ShpGeometry.java │ └── geotools │ ├── GeoToolsUtils.java │ └── GeometryCreator.java └── resources ├── application.properties └── logback-boot.xml /README.md: -------------------------------------------------------------------------------- 1 | # Spring-Boot-ShpReader 2 | Spring-Boot结合geotools工具包,实现shpfile文件的读取,以及数据存储,并最终能显示其几何信息(可视化)以及创建我们自己的shp文件! 3 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.appleyk 5 | Spring-Boot-ShpReader 6 | 0.0.1-SNAPSHOT 7 | shp文件的读取 8 | 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 2.1.4.RELEASE 14 | 15 | 16 | 17 | 20.0 18 | 42.1.4 19 | 20 | 21 | 22 | osgeo 23 | OSGeo Release Repository 24 | https://repo.osgeo.org/repository/release/ 25 | 26 | false 27 | 28 | 29 | true 30 | 31 | 32 | 33 | osgeo-snapshot 34 | OSGeo Snapshot Repository 35 | https://repo.osgeo.org/repository/snapshot/ 36 | 37 | true 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-web 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-devtools 62 | 63 | 64 | true 65 | 66 | 67 | 68 | junit 69 | junit 70 | 71 | 72 | 73 | 74 | org.geotools 75 | gt-shapefile 76 | ${geotools.version} 77 | 78 | 79 | 80 | org.geotools 81 | gt-swing 82 | ${geotools.version} 83 | 84 | 85 | 86 | 87 | 88 | 89 | org.geotools.jdbc 90 | gt-jdbc-postgis 91 | ${geotools.version} 92 | 93 | 94 | 95 | 96 | org.postgresql 97 | postgresql 98 | ${postgresql.version} 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /src/main/java/com/appleyk/Application.java: -------------------------------------------------------------------------------- 1 | package com.appleyk; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 7 | import org.springframework.web.context.annotation.ApplicationScope; 8 | 9 | /** 10 | * 11 | * 下面是一个典型的结构: 12 | * 13 | * com +- example +- myproject +- Application.java -- 14 | * 注意这个位置,习惯性的放在项目的一开始,也就是根包的第一层 | + - domain | +- Customer.java | +- 15 | * CustomerRepository.java | + - service | +- CustomerService.java | + - web +- 16 | * CustomerController.java 17 | * 18 | * 19 | * 文件将声明 main 方法, 还有基本的 @Configuration 20 | * 21 | * @author yukun24@126.com 22 | * @date 2018年4月24日08:59:07 23 | */ 24 | 25 | @SpringBootApplication 26 | public class Application extends SpringBootServletInitializer { 27 | 28 | /** 29 | * SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式。 在很多情况下, 你只需委托给 30 | * SpringApplication.run这个静态方法: 31 | * 32 | * @param args 33 | */ 34 | public static void main(String[] args) { 35 | 36 | SpringApplication.run(Application.class, args); 37 | 38 | } 39 | 40 | @Override 41 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 42 | return application.sources(Application.class); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/appleyk/entity/ShpGeometry.java: -------------------------------------------------------------------------------- 1 | package com.appleyk.entity; 2 | 3 | /** 4 | * 以shp文件的内容,构建对应的Java实体类 5 | * @author yukun24@126.com 6 | * @blob http://blog.csdn.net/appleyk 7 | * @date 2018年4月24日-上午9:11:27 8 | */ 9 | public class ShpGeometry { 10 | private int gid; 11 | private String osm_id; 12 | private String fclass; 13 | private int code; 14 | private String name; 15 | private String type; 16 | private Object geom; 17 | 18 | public ShpGeometry() { 19 | 20 | } 21 | 22 | public int getGid() { 23 | return gid; 24 | } 25 | 26 | public void setGid(int gid) { 27 | this.gid = gid; 28 | } 29 | 30 | public String getOsm_id() { 31 | return osm_id; 32 | } 33 | 34 | public void setOsm_id(String osm_id) { 35 | if (osm_id.equals("")) { 36 | this.osm_id = null; 37 | }else this.osm_id = osm_id; 38 | } 39 | 40 | public String getFclass() { 41 | 42 | return fclass; 43 | } 44 | 45 | public void setFclass(String fclass) { 46 | if (fclass.equals("")) { 47 | this.fclass = null; 48 | }else this.fclass = fclass; 49 | 50 | } 51 | 52 | public int getCode() { 53 | return code; 54 | } 55 | 56 | public void setCode(int code) { 57 | this.code = code; 58 | } 59 | 60 | public String getName() { 61 | 62 | return name; 63 | } 64 | 65 | public void setName(String name) { 66 | 67 | if (name.equals("")) { 68 | this.name = null; 69 | }else this.name = name; 70 | 71 | } 72 | 73 | public String getType() { 74 | return type; 75 | } 76 | 77 | public void setType(String type) { 78 | if (type.equals("")) { 79 | this.type = null; 80 | }else this.type = type; 81 | } 82 | 83 | public Object getGeom() { 84 | return geom; 85 | } 86 | 87 | public void setGeom(Object geom) { 88 | this.geom = geom; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/appleyk/geotools/GeoToolsUtils.java: -------------------------------------------------------------------------------- 1 | package com.appleyk.geotools; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.io.Serializable; 6 | import java.nio.charset.Charset; 7 | import java.sql.Connection; 8 | import java.sql.DriverManager; 9 | import java.sql.PreparedStatement; 10 | import java.sql.ResultSet; 11 | import java.sql.Statement; 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.HashMap; 15 | import java.util.Iterator; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | import org.geotools.data.DataStore; 20 | import org.geotools.data.DataStoreFinder; 21 | import org.geotools.data.FeatureSource; 22 | import org.geotools.data.FeatureWriter; 23 | import org.geotools.data.FileDataStore; 24 | import org.geotools.data.FileDataStoreFinder; 25 | import org.geotools.data.Transaction; 26 | import org.geotools.data.postgis.PostgisNGDataStoreFactory; 27 | import org.geotools.data.shapefile.ShapefileDataStore; 28 | import org.geotools.data.shapefile.ShapefileDataStoreFactory; 29 | import org.geotools.data.shapefile.files.ShpFiles; 30 | import org.geotools.data.shapefile.shp.ShapefileReader; 31 | import org.geotools.data.simple.SimpleFeatureSource; 32 | import org.geotools.feature.FeatureCollection; 33 | import org.geotools.feature.FeatureIterator; 34 | import org.geotools.feature.simple.SimpleFeatureTypeBuilder; 35 | import org.geotools.map.FeatureLayer; 36 | import org.geotools.map.Layer; 37 | import org.geotools.map.MapContent; 38 | import org.geotools.referencing.crs.DefaultGeographicCRS; 39 | import org.geotools.styling.SLD; 40 | import org.geotools.styling.Style; 41 | import org.geotools.swing.JMapFrame; 42 | import org.geotools.swing.data.JFileDataStoreChooser; 43 | import org.locationtech.jts.geom.Geometry; 44 | import org.locationtech.jts.geom.GeometryFactory; 45 | import org.locationtech.jts.geom.MultiPolygon; 46 | import org.opengis.feature.Property; 47 | import org.opengis.feature.simple.SimpleFeature; 48 | import org.opengis.feature.simple.SimpleFeatureType; 49 | 50 | import com.appleyk.entity.ShpGeometry; 51 | 52 | public class GeoToolsUtils { 53 | 54 | static Connection connection = null; 55 | static DataStore pgDatastore = null; 56 | @SuppressWarnings("rawtypes") 57 | static FeatureSource fSource = null; 58 | static Statement statement = null; 59 | static GeometryCreator gCreator = GeometryCreator.getInstance(); 60 | static GeometryFactory geometryFactory = new GeometryFactory(); 61 | 62 | /** 63 | * 1.连接postgrepsql数据库 64 | * 65 | * @param ip 66 | * @param port 67 | * @param user 68 | * @param password 69 | * @param database 70 | * @return 71 | * @throws Exception 72 | */ 73 | private static boolean connDataBase(String ip, Integer port, String user, String password, String database) 74 | throws Exception { 75 | 76 | // "jdbc:postgresql://192.168.1.104:5432/test" 77 | // user=postgres 78 | // password=bluethink134 79 | 80 | // 拼接url 81 | String url = "jdbc:postgresql://" + ip + ":" + port + "/" + database; 82 | Class.forName("org.postgresql.Driver"); // 一定要注意和上面的MySQL语法不同 83 | connection = DriverManager.getConnection(url, user, password); 84 | if (connection != null) { 85 | return true; 86 | } else { 87 | return false; 88 | } 89 | } 90 | 91 | /** 92 | * 2.连接数据库 使用的postgis 链接代码如下: 93 | * 94 | * @param dbtype 95 | * @param host 96 | * @param port 97 | * @param database 98 | * @param userName 99 | * @param password 100 | */ 101 | private static void connPostGis(String dbtype, String host, int port, String database, String userName, 102 | String password) { 103 | 104 | Map params = new HashMap(); 105 | 106 | params.put(PostgisNGDataStoreFactory.DBTYPE.key, dbtype); 107 | params.put(PostgisNGDataStoreFactory.HOST.key, host); 108 | params.put(PostgisNGDataStoreFactory.PORT.key, new Integer(port)); 109 | params.put(PostgisNGDataStoreFactory.DATABASE.key, database); 110 | params.put(PostgisNGDataStoreFactory.SCHEMA.key, "public"); 111 | params.put(PostgisNGDataStoreFactory.USER.key, userName); 112 | params.put(PostgisNGDataStoreFactory.PASSWD.key, password); 113 | try { 114 | pgDatastore = DataStoreFinder.getDataStore(params); 115 | if (pgDatastore != null) { 116 | System.out.println("系统连接到位于:" + host + "的空间数据库" + database + "成功!"); 117 | } else { 118 | System.out.println("系统连接到位于:" + host + "的空间数据库" + database + "失败!请检查相关参数"); 119 | } 120 | } catch (IOException e) { 121 | e.printStackTrace(); 122 | System.out.println("系统连接到位于:" + host + "的空间数据库" + database + "失败!请检查相关参数"); 123 | } 124 | 125 | } 126 | 127 | /** 128 | * 利用GeoTools工具包,打开一张shapfile文件,并显示 129 | * 130 | * @throws Exception 131 | */ 132 | public static void openShpFile() throws Exception { 133 | 134 | // 1.数据源选择 shp扩展类型的 135 | File file = JFileDataStoreChooser.showOpenFile("shp", null); 136 | if (file == null) { 137 | return; 138 | } 139 | 140 | // 2.得到打开的文件的数据源 141 | FileDataStore store = FileDataStoreFinder.getDataStore(file); 142 | 143 | // 3.设置数据源的编码,防止中文乱码 144 | ((ShapefileDataStore) store).setCharset(Charset.forName("UTF-8")); 145 | 146 | /** 147 | * 使用FeatureSource管理要素数据 使用Style(SLD)管理样式 使用Layer管理显示 148 | * 使用MapContent管理所有地图相关信息 149 | */ 150 | 151 | // 4.以java对象的方式访问地理信息 152 | // 简单地理要素 153 | SimpleFeatureSource featureSource = store.getFeatureSource(); 154 | 155 | // 5.创建映射内容,并将我们的shapfile添加进去 156 | MapContent mapContent = new MapContent(); 157 | 158 | // 6.设置容器的标题 159 | mapContent.setTitle("Appleyk's GeoTools"); 160 | 161 | // 7.创建简单样式 162 | Style style = SLD.createSimpleStyle(featureSource.getSchema()); 163 | 164 | // 8.显示【shapfile地理信息+样式】 165 | Layer layer = new FeatureLayer(featureSource, style); 166 | 167 | // 9.将显示添加进map容器 168 | mapContent.addLayer(layer); 169 | 170 | // 10.窗体打开,高大尚的操作开始 171 | JMapFrame.showMap(mapContent); 172 | 173 | } 174 | 175 | public static void readSHP(String path) throws Exception { 176 | 177 | // 一个数据存储实现,允许从Shapefiles读取和写入 178 | ShapefileDataStore shpDataStore = null; 179 | shpDataStore = new ShapefileDataStore(new File(path).toURI().toURL()); 180 | shpDataStore.setCharset(Charset.forName("UTF-8")); 181 | 182 | // 获取这个数据存储保存的类型名称数组 183 | // getTypeNames:获取所有地理图层 184 | String typeName = shpDataStore.getTypeNames()[0]; 185 | 186 | // 通过此接口可以引用单个shapefile、数据库表等。与数据存储进行比较和约束 187 | FeatureSource featureSource = null; 188 | featureSource = (FeatureSource) shpDataStore.getFeatureSource(typeName); 189 | 190 | // 一个用于处理FeatureCollection的实用工具类。提供一个获取FeatureCollection实例的机制 191 | FeatureCollection result = featureSource.getFeatures(); 192 | 193 | FeatureIterator iterator = result.features(); 194 | 195 | // 迭代 特征 只迭代100个 太大了,一下子迭代完,非常耗时 196 | int stop = 0; 197 | List geolist = new ArrayList(); 198 | while (iterator.hasNext()) { 199 | 200 | if (stop > 100) { 201 | break; 202 | } 203 | 204 | SimpleFeature feature = iterator.next(); 205 | Collection p = feature.getProperties(); 206 | Iterator it = p.iterator(); 207 | // 构建实体 208 | ShpGeometry geo = new ShpGeometry(); 209 | 210 | // 特征里面的属性再迭代,属性里面有字段 211 | String name; 212 | while (it.hasNext()) { 213 | 214 | Property pro = it.next(); 215 | name = pro.getName().toString(); 216 | 217 | /** 218 | * 根据shp文件里面的属性值进行过滤 219 | */ 220 | if (name.equals("the_geom")) { 221 | geo.setGeom(pro.getValue()); 222 | } 223 | 224 | if (name.equals("osm_id")) { 225 | geo.setOsm_id(pro.getValue().toString()); 226 | } 227 | 228 | if (name.equals("code")) { 229 | geo.setCode(Integer.parseInt(pro.getValue().toString())); 230 | } 231 | 232 | if (name.equals("fclass")) { 233 | geo.setFclass(pro.getValue().toString()); 234 | } 235 | 236 | if (name.equals("name")) { 237 | geo.setName(pro.getValue().toString()); 238 | } 239 | 240 | if (name.equals("type")) { 241 | geo.setType(pro.getValue().toString()); 242 | } 243 | 244 | } // end 里层while 245 | 246 | geolist.add(geo); 247 | stop++; 248 | 249 | } // end 最外层 while 250 | 251 | iterator.close(); 252 | boolean bRes = true; 253 | for (ShpGeometry geo : geolist) { 254 | /** 255 | * 存储对象geo,这里是循环插入,也可以做成mybatis的批量insert 256 | */ 257 | if (!shpSave(geo)) { 258 | bRes = false; 259 | break; 260 | } 261 | } 262 | 263 | if (bRes) { 264 | System.out.println("读取shapefile文件内容并插入数据库成功!"); 265 | } 266 | } 267 | 268 | /** 269 | * 存储shp文件的数据 == 文件内容映射成Java实体类存储在postgresql数据库中 270 | * 271 | * @param geo 272 | * @return 273 | * @throws Exception 274 | */ 275 | public static boolean shpSave(ShpGeometry geo) throws Exception { 276 | 277 | boolean result = false; 278 | String sql = "insert into geotable (osm_id,code,fclass,name,type,geom) values('" + geo.getOsm_id() + "','" 279 | + geo.getCode() + "','" + geo.getFclass() + "','" + geo.getName() + "','" + geo.getType() + "'," 280 | + "st_geomfromewkt('" + geo.getGeom().toString() + "'))"; 281 | 282 | PreparedStatement pstmt; 283 | pstmt = connection.prepareStatement(sql); 284 | 285 | // geometry = st_geomfromewkt(text WKT) == 286 | // 对应postgresql中的几何WKT文本描述转换为几何数据 287 | 288 | System.out.println(sql); 289 | int i = pstmt.executeUpdate(); 290 | if (i > 0) { 291 | result = true; 292 | } 293 | 294 | pstmt.close(); 295 | return result; 296 | } 297 | 298 | /** 299 | * 获取POSTGIS中所有的地理图层 300 | * 301 | * @throws Exception 302 | */ 303 | public static void getAllLayers() throws Exception { 304 | String[] typeName = pgDatastore.getTypeNames(); 305 | for (int i = 0; i < typeName.length; i++) { 306 | System.out.println((i + 1) + ":" + typeName[i]); 307 | } 308 | } 309 | 310 | /** 311 | * 针对某个地理图层[相当于table表名字],进行地理信息的读取 312 | * 313 | * @param Schema 314 | * @throws Exception 315 | */ 316 | @SuppressWarnings("unchecked") 317 | public static void postGisReading(String Schema) throws Exception { 318 | 319 | fSource = pgDatastore.getFeatureSource(Schema); 320 | // 1.一个用于处理FeatureCollection的实用工具类。提供一个获取FeatureCollection实例的机制 321 | FeatureCollection result = fSource.getFeatures(); 322 | 323 | // 2.计算本图层中所有特征的数量 324 | System.out.println("特征totalCount = " + result.size()); 325 | 326 | // 3.迭代特征 327 | FeatureIterator iterator = result.features(); 328 | 329 | // 4.迭代特征 只迭代30个 太大了,一下子迭代完,非常耗时 330 | int stop = 0; 331 | while (iterator.hasNext()) { 332 | 333 | if (stop > 30) { 334 | break; 335 | } 336 | 337 | SimpleFeature feature = iterator.next(); 338 | Collection p = feature.getProperties(); 339 | Iterator it = p.iterator(); 340 | 341 | // 5.特征里面的属性再迭代,属性里面有字段 342 | System.out.println("================================"); 343 | while (it.hasNext()) { 344 | Property pro = it.next(); 345 | System.out.println(pro.getName() + "\t = " + pro.getValue()); 346 | } // end 里层while 347 | stop++; 348 | } // end 最外层 while 349 | iterator.close(); 350 | } 351 | 352 | /** 353 | * 根据几何对象名称 查询几何对象信息 [Query] 354 | * @param name 355 | * @throws Exception 356 | */ 357 | public static void Query(String name) throws Exception{ 358 | 359 | //String sql = "select st_astext(geom) from geotable where name ='"+name+"'"; 360 | String sql = "select geometrytype(geom) as type,st_astext(geom) as geom from geotable where name ='"+name+"'"; 361 | statement = connection.createStatement(); 362 | ResultSet result = statement.executeQuery(sql); 363 | if(result!=null){ 364 | while(result.next()){ 365 | Object val = result.getString(1); 366 | if(val.equals("MULTIPOLYGON")){ 367 | System.out.println("几何对象类型:多多边形"); 368 | MultiPolygon mPolygon = gCreator.createMulPolygonByWKT(result.getString(2)); 369 | System.out.println(mPolygon instanceof MultiPolygon); 370 | System.out.println("获取几何对象中的点个数:"+mPolygon.getNumPoints()); 371 | } 372 | 373 | } 374 | } 375 | } 376 | 377 | /** 378 | * 将几何对象信息写入一个shapfile文件并读取 379 | * @throws Exception 380 | */ 381 | public static void writeSHP(String path, Geometry geometry) throws Exception{ 382 | 383 | //String path="C:\\my.shp"; 384 | 385 | // 1.创建shape文件对象 386 | File file =new File(path); 387 | 388 | Map params = new HashMap(); 389 | 390 | // 2.用于捕获参数需求的数据类 391 | //URLP:url to the .shp file. 392 | params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL()); 393 | 394 | // 3.创建一个新的数据存储——对于一个还不存在的文件。 395 | ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params); 396 | 397 | 398 | // 4.定义图形信息和属性信息 399 | //SimpleFeatureTypeBuilder 构造简单特性类型的构造器 400 | SimpleFeatureTypeBuilder tBuilder = new SimpleFeatureTypeBuilder(); 401 | 402 | // 5.设置 403 | //WGS84:一个二维地理坐标参考系统,使用WGS84数据 404 | tBuilder.setCRS(DefaultGeographicCRS.WGS84); 405 | tBuilder.setName("shapefile"); 406 | 407 | // 6.添加 一个多多边形 == 这里也可以当做参数传过来,具体情况具体对待 408 | tBuilder.add("the_geom", MultiPolygon.class); 409 | // 7.添加一个id 410 | tBuilder.add("osm_id", Long.class); 411 | // 8.添加名称 412 | tBuilder.add("name", String.class); 413 | 414 | // 9.添加描述 415 | tBuilder.add("des", String.class); 416 | 417 | 418 | // 10.设置此数据存储的特征类型 419 | ds.createSchema(tBuilder.buildFeatureType()); 420 | 421 | // 11.设置编码 422 | ds.setCharset(Charset.forName("UTF-8")); 423 | 424 | 425 | 426 | // 12.设置writer 427 | //为给定的类型名称创建一个特性写入器 428 | FeatureWriter writer = ds.getFeatureWriter( 429 | ds.getTypeNames()[0], Transaction.AUTO_COMMIT); 430 | 431 | 432 | 433 | //Interface SimpleFeature:一个由固定列表值以已知顺序组成的SimpleFeatureType实例。 434 | // 13.写一个点 435 | SimpleFeature feature = writer.next(); 436 | feature.setAttribute("the_geom", geometry); 437 | feature.setAttribute("osm_id", 1234567890l); 438 | feature.setAttribute("name", "多多边形"); 439 | feature.setAttribute("des", "国家大剧院"); 440 | 441 | // 14.写入 442 | writer.write(); 443 | 444 | // 15.关闭 445 | writer.close(); 446 | 447 | // 16.释放资源 448 | ds.dispose(); 449 | 450 | 451 | // 17.读取shapefile文件的图形信息 452 | ShpFiles shpFiles = new ShpFiles(path); 453 | /*ShapefileReader( 454 | ShpFiles shapefileFiles, 455 | boolean strict, --是否是严格的、精确的 456 | boolean useMemoryMapped,--是否使用内存映射 457 | GeometryFactory gf, --几何图形工厂 458 | boolean onlyRandomAccess--是否只随机存取 459 | ) 460 | */ 461 | ShapefileReader reader = new ShapefileReader(shpFiles, 462 | false, true, new GeometryFactory(), false); 463 | while(reader.hasNext()){ 464 | System.out.println(reader.nextRecord().shape()); 465 | } 466 | reader.close(); 467 | } 468 | 469 | public static void main(String[] args) throws Exception { 470 | 471 | // 1.利用Provider连接 空间数据库 472 | if (!connDataBase("192.168.1.104", 5432, "postgres", "bluethink", "test")) { 473 | System.out.println("连接postgresql数据库失败,请检查参数!"); 474 | } 475 | 476 | System.out.println("===============连接postgis空间数据库=============="); 477 | connPostGis("postgis", "192.168.1.104", 5432, "test", "postgres", "bluethink"); 478 | 479 | System.out.println("===============读取shp文件并存储至postgresql数据库=============="); 480 | // A.建筑物的shapefile,多边形 MULTIPOLYGON 481 | // String path = "E:\\china-latest-free\\gis.osm_buildings_a_free_1.shp"; 482 | 483 | // B.路的shapefile,多线MULTILINESTRING 484 | // String path = "E:\\china-latest-free\\gis.osm_roads_free_1.shp"; 485 | 486 | // C.建筑物的点坐标 以Point为主 487 | // String path = "E:\\china-latest-free\\gis.osm_pois_free_1.shp"; 488 | 489 | String path = "E:\\china-latest-free\\gis.osm_buildings_a_free_1.shp"; 490 | readSHP(path); 491 | 492 | System.out.println("===============读取图层geotable=============="); 493 | postGisReading("geotable"); 494 | 495 | System.out.println("===============获取所有图层【所有空间几何信息表】=============="); 496 | getAllLayers(); 497 | 498 | System.out.println("===============创建自己的shp文件=============="); 499 | String MPolygonWKT="MULTIPOLYGON(((116.3824004 39.9032955,116.3824261 39.9034733,116.382512 39.9036313,116.382718 39.9038025,116.3831643 39.903954,116.383602 39.9040198,116.3840827 39.9040001,116.3844003 39.9039211,116.3846921 39.903763,116.3848552 39.9035787,116.3848981 39.9033548,116.3848037 39.9031244,116.3845719 39.9029071,116.3842286 39.9027754,116.3837823 39.9027227,116.3833789 39.9027095,116.383027 39.902749,116.3828038 39.9028346,116.382615 39.90294,116.3824776 39.9030717,116.3824004 39.9032955)))"; 500 | MultiPolygon multiPolygon = gCreator.createMulPolygonByWKT(MPolygonWKT); 501 | System.out.println(multiPolygon.getGeometryType()); 502 | //首先得创建my这个目录 503 | writeSHP("C:/my/multipol.shp",multiPolygon); 504 | System.out.println("===============打开shp文件=============="); 505 | GeoToolsUtils.openShpFile(); 506 | } 507 | } 508 | -------------------------------------------------------------------------------- /src/main/java/com/appleyk/geotools/GeometryCreator.java: -------------------------------------------------------------------------------- 1 | package com.appleyk.geotools; 2 | 3 | 4 | import org.locationtech.jts.geom.*; 5 | import org.locationtech.jts.io.ParseException; 6 | import org.locationtech.jts.io.WKTReader; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 几何对象构建器 12 | * 13 | * @author yukun24@126.com 14 | * @blob http://blog.csdn.net/appleyk 15 | * @version V1.0.1 16 | * @date 2017年12月8日10:38:49 17 | */ 18 | 19 | //单例模式 20 | public class GeometryCreator { 21 | 22 | public static GeometryCreator geometryCreator = null; 23 | 24 | private GeometryFactory geometryFactory = new GeometryFactory(); 25 | 26 | private GeometryCreator() { 27 | } 28 | 29 | /** 30 | * 返回本类的唯一实例 31 | * @return 32 | */ 33 | public static GeometryCreator getInstance() { 34 | if (geometryCreator == null) { 35 | return new GeometryCreator(); 36 | } 37 | return geometryCreator; 38 | } 39 | 40 | 41 | /** 42 | * 1.构建点 43 | */ 44 | 45 | /** 46 | * 1.1根据X,Y坐标构建一个几何对象: 点 【Point】 47 | * @param x 48 | * @param y 49 | * @return 50 | */ 51 | public Point createPoint(double x,double y){ 52 | Coordinate coord = new Coordinate(x, y); 53 | Point point = geometryFactory.createPoint(coord); 54 | return point; 55 | } 56 | 57 | /** 58 | * 1.2根据几何对象的WKT描述【String】创建几何对象: 点 【Point】 59 | * @return 60 | * @throws ParseException 61 | */ 62 | public Point createPointByWKT(String PointWKT) throws ParseException { 63 | WKTReader reader = new WKTReader(geometryFactory); 64 | Point point = (Point) reader.read(PointWKT); 65 | return point; 66 | } 67 | 68 | /** 69 | * 1.3根据几何对象的WKT描述【String】创建几何对象:多点 【MultiPoint】 70 | * @return 71 | * @throws ParseException 72 | */ 73 | public MultiPoint createMulPointByWKT(String MPointWKT)throws ParseException{ 74 | WKTReader reader = new WKTReader( geometryFactory ); 75 | MultiPoint mpoint = (MultiPoint) reader.read(MPointWKT); 76 | return mpoint; 77 | } 78 | 79 | 80 | /** 81 | * 2.构建线 82 | */ 83 | 84 | 85 | /** 86 | * 2.1根据两点 创建几何对象:线 【LineString】 87 | * @param ax 88 | * @param ay 89 | * @param bx 90 | * @param by 91 | * @return 92 | */ 93 | public LineString createLine(double ax,double ay,double bx,double by){ 94 | Coordinate[] coords = new Coordinate[] {new Coordinate(ax, ay), new Coordinate(bx, by)}; 95 | LineString line = geometryFactory.createLineString(coords); 96 | return line; 97 | } 98 | 99 | /** 100 | * 2.2根据线的WKT描述创建几何对象:线 【LineString】 101 | * @param LineStringWKT 102 | * @return 103 | * @throws ParseException 104 | */ 105 | public LineString createLineByWKT(String LineStringWKT) throws ParseException{ 106 | WKTReader reader = new WKTReader( geometryFactory ); 107 | LineString line = (LineString) reader.read("LINESTRING(0 0, 2 0)"); 108 | return line; 109 | } 110 | 111 | /** 112 | * 2.3根据点组合的线数组,创建几何对象:多线 【MultiLineString】 113 | * @param list 114 | * @return 115 | */ 116 | public MultiLineString createMLine(List list){ 117 | 118 | MultiLineString ms = null; 119 | 120 | 121 | if(list == null){ 122 | return ms; 123 | } 124 | 125 | LineString[] lineStrings = new LineString[list.size()]; 126 | 127 | 128 | // Coordinate[] coords1 = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)}; 129 | // LineString line1 = geometryFactory.createLineString(coords1); 130 | // 131 | // Coordinate[] coords2 = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)}; 132 | // LineString line2 = geometryFactory.createLineString(coords2); 133 | 134 | int i = 0; 135 | for (Coordinate[] coordinates : list) { 136 | lineStrings[i] = geometryFactory.createLineString(coordinates); 137 | } 138 | 139 | ms = geometryFactory.createMultiLineString(lineStrings); 140 | 141 | return ms; 142 | } 143 | 144 | 145 | /** 146 | * 2.4根据几何对象的WKT描述【String】创建几何对象 : 多线【MultiLineString】 147 | * @param MLineStringWKT 148 | * @return 149 | * @throws ParseException 150 | */ 151 | public MultiLineString createMLineByWKT(String MLineStringWKT)throws ParseException{ 152 | WKTReader reader = new WKTReader( geometryFactory ); 153 | MultiLineString line = (MultiLineString) reader.read(MLineStringWKT); 154 | return line; 155 | } 156 | 157 | 158 | 159 | /** 160 | * 3.构建多边形 161 | */ 162 | 163 | 164 | /** 165 | * 3.1 根据几何对象的WKT描述【String】创建几何对象:多边形 【Polygon】 166 | * @param PolygonWKT 167 | * @return 168 | * @throws ParseException 169 | */ 170 | public Polygon createPolygonByWKT(String PolygonWKT) throws ParseException{ 171 | WKTReader reader = new WKTReader( geometryFactory ); 172 | Polygon polygon = (Polygon) reader.read(PolygonWKT); 173 | return polygon; 174 | } 175 | 176 | /** 177 | * 3.2 根据几何对象的WKT描述【String】创建几何对象: 多多边形 【MultiPolygon】 178 | * @param MPolygonWKT 179 | * @return 180 | * @throws ParseException 181 | */ 182 | public MultiPolygon createMulPolygonByWKT(String MPolygonWKT) throws ParseException{ 183 | WKTReader reader = new WKTReader( geometryFactory ); 184 | MultiPolygon mpolygon = (MultiPolygon) reader.read(MPolygonWKT); 185 | return mpolygon; 186 | } 187 | 188 | /** 189 | * 根据多边形数组 进行多多边形的创建 190 | * @param polygons 191 | * @return 192 | * @throws ParseException 193 | */ 194 | public MultiPolygon createMulPolygonByPolygon(Polygon[] polygons) throws ParseException{ 195 | 196 | return geometryFactory.createMultiPolygon(polygons); 197 | } 198 | 199 | /** 200 | * 4.构建几何对象集合 201 | */ 202 | 203 | 204 | /** 205 | * 4.1 根据几何对象数组,创建几何对象集合:【GeometryCollection】 206 | * @return 207 | * @throws ParseException 208 | */ 209 | public GeometryCollection createGeoCollect(Geometry[] geoArray) throws ParseException{ 210 | // LineString line = createLine(125.12,25.4,85.63,99.99); 211 | // Polygon poly = createPolygonByWKT("POLYGON((20 10, 30 0, 40 10, 30 20, 20 10))"); 212 | // Geometry g1 = geometryFactory.createGeometry(line); 213 | // Geometry g2 = geometryFactory.createGeometry(poly); 214 | // Geometry[] geoArray = new Geometry[]{g1,g2}; 215 | GeometryCollection gc = geometryFactory.createGeometryCollection(geoArray); 216 | return gc; 217 | } 218 | 219 | 220 | 221 | /** 222 | * 5.构建圆 223 | */ 224 | 225 | /** 226 | * 5.1 根据圆点以及半径创建几何对象:特殊的多边形--圆 【Polygon】 227 | * @param x 228 | * @param y 229 | * @param RADIUS 230 | * @return 231 | */ 232 | public Polygon createCircle(double x, double y, final double RADIUS){ 233 | 234 | final int SIDES = 32;//圆上面的点个数 235 | 236 | Coordinate coords[] = new Coordinate[SIDES+1]; 237 | for( int i = 0; i < SIDES; i++){ 238 | double angle = ((double) i / (double) SIDES) * Math.PI * 2.0; 239 | double dx = Math.cos( angle ) * RADIUS; 240 | double dy = Math.sin( angle ) * RADIUS; 241 | coords[i] = new Coordinate( (double) x + dx, (double) y + dy ); 242 | } 243 | coords[SIDES] = coords[0]; 244 | //线性环 245 | LinearRing ring = geometryFactory.createLinearRing(coords); 246 | Polygon polygon = geometryFactory.createPolygon(ring, null); 247 | return polygon; 248 | } 249 | 250 | 251 | /** 252 | * 6.构建环 253 | */ 254 | 255 | /** 256 | * 6.1 根据WKT创建环 257 | * @param ringWKT 258 | * @return 259 | * @throws ParseException 260 | */ 261 | public LinearRing createLinearRingByWKT(String ringWKT) throws ParseException{ 262 | WKTReader reader = new WKTReader( geometryFactory ); 263 | LinearRing ring = (LinearRing) reader.read(ringWKT); 264 | return ring; 265 | } 266 | 267 | } 268 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8080 2 | server.session.timeout=10 3 | server.tomcat.uri-encoding=utf8 4 | 5 | #在application.properties文件中引入日志配置文件 6 | #===================================== log ============================= 7 | logging.config=classpath:logback-boot.xml 8 | -------------------------------------------------------------------------------- /src/main/resources/logback-boot.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d %p (%file:%line\)- %m%n 8 | 9 | UTF-8 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | opt/spring-boot-web/logs/sys.log 19 | 20 | 21 | 22 | 23 | 24 | log/sys.%d.%i.log 25 | 26 | 30 27 | 28 | 29 | 10MB 30 | 31 | 32 | 33 | 34 | 35 | %d %p (%file:%line\)- %m%n 36 | 37 | 38 | UTF-8 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | --------------------------------------------------------------------------------