Spring-Boot ☞ ShapeFile文件读写工具类+接口调用
程序员文章站
2022-10-17 09:43:30
一、项目目录结构树 二、项目启动 三、往指定的shp文件里写内容 (1) json数据【Post】 (2)接口调用 (3)QGIS查看,验证数据有效性 四、读取指定shp文件,并显示内容 (1)接口调用 (2)QGIS显示北京故宫【shp文件在项目中的static文件夹下】 五、将指定的shp文件转 ......
一、项目目录结构树
二、项目启动
三、往指定的shp文件里写内容
(1) json数据【post】
{ "name":"test", "path":"c:/test", "geom":"multipolygon(((101.870371 25.19228,101.873633 25.188183,101.880564 25.184416,101.886808 25.186028,101.892043 25.189969,101.896592 25.190163,101.903716 25.190785,101.905454 25.193464,101.899897 25.196202,101.894146 25.197911,101.891657 25.19826,101.886078 25.197658,101.884211145538 25.2007060137013,101.88172564506 25.1949712942389,101.87874 25.199619,101.874641 25.200998,101.868547 25.202415,101.863741 25.202415,101.85887 25.202842,101.854557 25.202182,101.852604 25.199736,101.852282 25.19628,101.854492 25.194183,101.855608 25.192668,101.863698 25.192105,101.870371 25.19228)))", "id":1001, "des":"湖泊水面" }
(2)接口调用
(3)qgis查看,验证数据有效性
四、读取指定shp文件,并显示内容
(1)接口调用
(2)qgis显示北京故宫【shp文件在项目中的static文件夹下】
五、将指定的shp文件转成image文件或流
(1) 接口调用 === 转image【png】文件
c盘下查看
(2) 接口调用 === 转image流,输出到客户端
六、核心工具类【shptools】
package com.appleyk.geotools; import com.appleyk.io.stringtokenreader; import com.appleyk.pojos.shpdatas; import com.appleyk.pojos.shpinfo; import com.appleyk.result.responsemessage; import com.appleyk.result.responseresult; import com.vividsolutions.jts.geom.*; import com.vividsolutions.jts.geom.point; import com.vividsolutions.jts.geom.polygon; import org.geotools.data.*; import org.geotools.data.shapefile.shapefiledatastore; import org.geotools.data.shapefile.shapefiledatastorefactory; import org.geotools.data.simple.simplefeaturesource; import org.geotools.feature.featurecollection; import org.geotools.feature.featureiterator; import org.geotools.feature.simple.simplefeaturetypebuilder; import org.geotools.geometry.jts.referencedenvelope; import org.geotools.map.featurelayer; import org.geotools.map.layer; import org.geotools.map.mapcontent; import org.geotools.referencing.crs.defaultgeographiccrs; import org.geotools.renderer.lite.streamingrenderer; import org.geotools.styling.sld; import org.geotools.styling.style; import org.geotools.swing.jmapframe; import org.geotools.swing.data.jfiledatastorechooser; import org.opengis.feature.property; import org.opengis.feature.simple.simplefeature; import org.opengis.feature.simple.simplefeaturetype; import org.springframework.util.resourceutils; import javax.imageio.imageio; import javax.servlet.http.httpservletresponse; import java.awt.*; import java.awt.image.bufferedimage; import java.io.file; import java.io.ioexception; import java.io.serializable; import java.nio.charset.charset; import java.util.collection; import java.util.hashmap; import java.util.map; /** * <p>shapefile读写工具类</p> * @author appleyk * @blob https://blog.csdn.net/appleyk * @date created on 上午 11:54 2018-10-12 */ public class shptools { /** * 集合对象构造器【自定义的】 */ private static geometrycreator gcreator = geometrycreator.getinstance(); /** * 边界 */ private static referencedenvelope bounds; // 画布的宽度 private static final int image_width = 2400; // 画布的高度 private static final int image_height = 1200; /** * 通过shp文件路径,读取shp内容 * @param filepath * @throws exception */ public static shpdatas readshpbypath(string filepath,integer limit) throws exception { // 一个数据存储实现,允许从shapefiles读取和写入 shapefiledatastore shpdatastore = new shapefiledatastore(new file(filepath).touri().tourl()); // 设置编码【防止中文乱码】 shpdatastore.setcharset(charset.forname("utf-8")); // gettypenames:获取所有地理图层,这里我只取第一个【如果是数据表,取出的就是表名】 string typename = shpdatastore.gettypenames()[0]; system.out.println("shp【图层】名称:"+typename); featurecollection<simplefeaturetype, simplefeature> result = getfeatures(shpdatastore, typename); // 迭代特征集合 featureiterator<simplefeature> iterator = result.features(); shpdatas shpdatas = new shpdatas(); shpdatas.setname(typename); shpdatas.setshppath(filepath); buildshpdatas(limit, iterator, shpdatas); iterator.close(); return shpdatas; } /** * 根据数据源及图层名称拿到特征集合 * @param shpdatastore * @param typename * @return * @throws ioexception */ private static featurecollection<simplefeaturetype, simplefeature> getfeatures(shapefiledatastore shpdatastore, string typename) throws ioexception { // 通过此接口可以引用单个shapefile、数据库表等。与数据存储进行比较和约束 featuresource<simplefeaturetype, simplefeature> featuresource = shpdatastore.getfeaturesource(typename); // 一个用于处理featurecollection的实用工具类。提供一个获取featurecollection实例的机制 featurecollection<simplefeaturetype, simplefeature> result = featuresource.getfeatures(); system.out.println("地理要素【记录】:"+result.size()+"个"); system.out.println("=================================="); return result; } /** * 构建shpdatas对象 * @param limit * @param iterator * @param shpdatas */ private static void buildshpdatas(integer limit, featureiterator<simplefeature> iterator, shpdatas shpdatas) { // 这里我们只迭代前limit个 int stop = 0; while (iterator.hasnext()) { if (stop > limit) { break; } // 拿到一个特征 simplefeature feature = iterator.next(); // 取出特征里面的属性集合 collection<property> p = feature.getproperties(); // 遍历属性集合 map<string,object> prop = new hashmap<>(); for (property pro : p) { string key = pro.getname().tostring(); string val = pro.getvalue().tostring(); prop.put(key, val); system.out.println("key【字段】:"+key+"\t|| value【值】:"+val); } system.out.println("\n============================ 序号:"+stop+"\n"); shpdatas.addprop(prop); stop++; } // end 最外层 while } /** * 将一个几何对象写进shapefile * @param filepath * @param geometry */ public static void writeshpbygeom(string filepath, geometry geometry) throws exception{ shapefiledatastore ds = getshpds(filepath, geometry); featurewriter<simplefeaturetype, simplefeature> writer = ds.getfeaturewriter(ds.gettypenames()[0], transaction.auto_commit); // interface simplefeature:一个由固定列表值以已知顺序组成的simplefeaturetype实例。 simplefeature feature = writer.next(); feature.setattribute("name", "xxxx名称"); feature.setattribute("path", "c:/test"); feature.setattribute("the_geom", geometry); feature.setattribute("id", 1010l); feature.setattribute("des", "xxxx描述"); system.out.println("========= 写入【"+geometry.getgeometrytype()+"】成功 !========="); // 写入 writer.write(); // 关闭 writer.close(); // 释放资源 ds.dispose(); } /** * 将一个几何对象写进shapefile * @param shpinfo */ public static responseresult writeshpbygeom(shpinfo shpinfo) throws exception{ // 特殊字符串解析器 stringtokenreader reader = new stringtokenreader(); // 根据几何对象的wkt字符串,反解【解析】成geometry对象 geometry geometry = reader.read(shpinfo.getgeom()); // 拿到shp对象所在的目录【文件夹】 string path = shpinfo.getpath(); file file = new file(path); if(!file.exists()){ file.mkdir(); } if(!file.isdirectory()){ return new responseresult(responsemessage.bad_request,"path不是有效的文件夹" ); } string filepath = shpinfo.getpath()+"/"+shpinfo.getname()+".shp"; shapefiledatastore ds = getshpds(filepath, geometry); string typename = ds.gettypenames()[0]; featurewriter<simplefeaturetype, simplefeature> writer ; if(shpinfo.isappendwrite()){ // 追加写几何对象 writer = ds.getfeaturewriterappend(typename, transaction.auto_commit); }else{ // 覆盖写几何对象 writer = ds.getfeaturewriter(typename, transaction.auto_commit); } // interface simplefeature:一个由固定列表值以已知顺序组成的simplefeaturetype实例。 simplefeature feature = writer.next(); feature.setattribute("name", shpinfo.getname()); feature.setattribute("path", shpinfo.getpath()); feature.setattribute("the_geom", geometry); feature.setattribute("id", shpinfo.getid()); feature.setattribute("des", shpinfo.getdes()); system.out.println("========= 写入【"+geometry.getgeometrytype()+"】成功 !========="); // 写入 writer.write(); // 关闭 writer.close(); // 释放资源 ds.dispose(); // 返回创建成功后的shp文件路径 return new responseresult(responsemessage.ok,filepath); } /** * 拿到配置好的datastore * @param filepath * @param geometry * @return * @throws ioexception */ private static shapefiledatastore getshpds(string filepath, geometry geometry) throws ioexception { // 1.创建shape文件对象 file file = new file(filepath); map<string, serializable> params = new hashmap<>(); // 2、用于捕获参数需求的数据类 urlp:url to the .shp file. params.put(shapefiledatastorefactory.urlp.key, file.touri().tourl()); // 3、创建一个新的数据存储【如果存在,则不创建】 shapefiledatastore ds = (shapefiledatastore) new shapefiledatastorefactory().createnewdatastore(params); // 4、定义图形信息和属性信息 -- simplefeaturetypebuilder 构造简单特性类型的构造器 simplefeaturetypebuilder tbuilder = new simplefeaturetypebuilder(); // 5、设置 -- wgs84:一个二维地理坐标参考系统,使用wgs84数据 tbuilder.setcrs(defaultgeographiccrs.wgs84); tbuilder.setname("shapefile"); // 添加名称 tbuilder.add("name", string.class); // 添加shp所在目录名称 tbuilder.add("path", string.class); // 添加 一个几何对象 tbuilder.add("the_geom", geometry.getclass()); // 添加一个id tbuilder.add("id", long.class); // 添加描述 tbuilder.add("des", string.class); // 设置此数据存储的特征类型 ds.createschema(tbuilder.buildfeaturetype()); // 设置编码 ds.setcharset(charset.forname("utf-8")); return ds; } /** * 打开shp文件,获取地图内容 * @param filepath 文件路径 * @param isopenbychoose 是否自定义打开shp文件 * @throws exception */ public static mapcontent getmapcontentbypath(string filepath,boolean isopenbychoose,string color) throws exception{ file file; if(isopenbychoose){ // 1.1、 数据源选择 shp扩展类型的 file = jfiledatastorechooser.showopenfile("shp", null); }else{ // 1.2、根据路径拿到文件对象 file = new file(filepath); } if(file==null){ return null; } // 2、得到打开的文件的数据源 filedatastore store = filedatastorefinder.getdatastore(file); // 3、设置数据源的编码,防止中文乱码 ((shapefiledatastore)store).setcharset(charset.forname("utf-8")); /** * 使用featuresource管理要素数据 * 使用style(sld)管理样式 * 使用layer管理显示 * 使用mapcontent管理所有地图相关信息 */ // 4、以java对象的方式访问地理信息 -- 简单地理要素 simplefeaturesource featuresource = store.getfeaturesource(); bounds = featuresource.getbounds(); // 5、创建映射内容,并将我们的shapfile添加进去 mapcontent mapcontent = new mapcontent(); // 6、设置容器的标题 mapcontent.settitle("appleyk's geotools"); color color1; if(color == null || "".equals(color)){ color1 = color.black; }else if("red".equals(color)){ color1 = color.red; }else if("green".equals(color)){ color1 = color.green; }else if("blue".equals(color)){ color1 = color.blue; }else{ color1 = color.orange; } // 7、创建简单样式 【颜色填充】 style style = sld.createsimplestyle(featuresource.getschema(),color1); // 8、显示【shapfile地理信息+样式】 layer layer = new featurelayer(featuresource, style); // 9、将显示添加进map容器 mapcontent.addlayer(layer); return mapcontent; } public static void showmap(mapcontent mapcontent){ jmapframe.showmap(mapcontent); } /** * shp文件转image【格式定png】 * @param shpfilepath shp目标文件 * @param destimagepath 转成图片的文件 == 如果没有,转成的图片写进response输出流里 * @param response 响应流 * @throws exception */ public static void shp2image(string shpfilepath,string destimagepath,string color, httpservletresponse response) throws exception{ // 流渲染器 streamingrenderer renderer = new streamingrenderer(); mapcontent mapcontent = getmapcontentbypath(shpfilepath,false,color ); renderer.setmapcontent(mapcontent); rectangle imagebounds = new rectangle(0, 0, image_width, image_height); bufferedimage dumpimage = new bufferedimage(image_width, image_height, bufferedimage.type_int_rgb); graphics2d g2d = dumpimage.creategraphics(); g2d.fillrect(0, 0, image_width, image_height); g2d.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on); renderer.paint(g2d, imagebounds, bounds); g2d.dispose(); if(destimagepath == null || "".equals(destimagepath)){ imageio.write(dumpimage, "png", response.getoutputstream()); }else{ imageio.write(dumpimage, "png", new file(destimagepath+".png")); } } public static void main(string[] args) throws exception{ file file = resourceutils.getfile("classpath:static/shptest[point]/dp_tl.shp"); // 从shp文件里面读取属性信息 readshpbypath(file.getabsolutepath(),10); system.out.println("=================下面开始往shp文件里面写几何对象==================="); // 先创建文件夹test string filepath = "c:/test/test.shp"; string pointwkt="point (120.76164848270959 31.22001141278534)"; point point = gcreator.createpointbywkt(pointwkt); // polygon【面】 string polygonwkt="polygon ((103.859188 34.695908, 103.85661 34.693788, 103.862027 34.69259, 103.863709 34.695078, 103.859188 34.695908))"; polygon polygon = gcreator.createpolygonbywkt(polygonwkt); // linestring【线】 string linestringwkt="linestring(113.511315990174 41.7274734296674,113.51492087909 41.7284983348307,113.516079593384 41.727649586406,113.515907932007 41.7262243043929,113.514019656861 41.7247989907606,113.512131381714 41.7250872589898,113.51138036319 41.7256637915682,113.511315990174 41.7274734296674)"; linestring linestring = gcreator.createlinebywkt(linestringwkt); // multipolygon【多面】 string multipolywkt = "multipolygon(((101.870371 25.19228,101.873633 25.188183,101.880564 25.184416,101.886808 25.186028,101.892043 25.189969,101.896592 25.190163,101.903716 25.190785,101.905454 25.193464,101.899897 25.196202,101.894146 25.197911,101.891657 25.19826,101.886078 25.197658,101.884211145538 25.2007060137013,101.88172564506 25.1949712942389,101.87874 25.199619,101.874641 25.200998,101.868547 25.202415,101.863741 25.202415,101.85887 25.202842,101.854557 25.202182,101.852604 25.199736,101.852282 25.19628,101.854492 25.194183,101.855608 25.192668,101.863698 25.192105,101.870371 25.19228)))"; multipolygon multipolygon = gcreator.createmulpolygonbywkt(multipolywkt); // 几何对象的范围【矩形边界】 envelope envelope = polygon.getenvelopeinternal(); system.out.println(envelope); // 往shp文件里面写几何对象 writeshpbygeom(filepath,point); } }
七、联系我
csdn名: appleyk
csdn博客:https://blog.csdn.net/appleyk
本篇csdn对应博文:https://blog.csdn.net/appleyk/article/details/83376510