leaflet地图的图层导出为shape文件,要求采用国家2000坐标系

leaflet地图上的图层导出为shape文件,要求采用国家2000坐标系
参考资料:
leaflet.js API:https://leafletjs.com/reference-1.6.0.html
WKT、WKB、GeoJSON:https://blog.csdn.net/xcymorningsun/article/details/89848096
选中图层,获取图层的属性:

var arrCoordinates = feature.geometry.coordinates;  //保存选中的图层的坐标
var arrProperties = feature.properties; 			//保存选中的图层的属性
var geometryType = feature.geometry.type; 			//保存选中的图层的类型

feature.geometry.coordinates获取到的坐标是这样的:[114.509255, 22.759991],要把它转换成x坐标以2开头,y坐标以5开头:[2519488.256,556778.197]。
点击导出(下载)按钮,下载图层为shp文件:

// 导出单个shp文件
function outFeayureshp() {
	var coordinates = wktGeometryType(geometryType,arrCoordinates);
	var form = $("<form></form>");
	form.attr("action",  "/map/leafletMap/outShp");
	form.attr("method", "post");
	form.attr("enctype", "multipart/form-data");
	form.append("<input type='input' name='coordinates' value='"+ JSON.stringify(coordinates) + "' />");
	form.append("<input type='input' name='arrProperties ' value='"+ JSON.stringify(arrProperties ) + "' />");
	form.append("<input type='input' name='geometryType' value='"+geometryType+"' />");
	$("body").append(form);
	form.submit();
	form.remove();
}
//区分图层类型的方法
function wktGeometryType(geometryType,coordinates){
	var coordinatesArrs = [];
	if(geometryType == "Point"){		//点
		var y = coordinates[0];
		var x = coordinates[1];
		var arr = [];
		var arrs = new Array();
		arrs = ctarr(x, y);
		arr = [ arrs[0], arrs[1] ];
		coordinatesArrs = arr;
	}else if(geometryType == "LineString"){		//线
		for (var i = 0; i < coordinates.length; i++) {
			var y = coordinates[i][0];
			var x = coordinates[i][1];
			var arr = [];
			var arrs = new Array();
			arrs = ctarr(x, y);
			arr = [ arrs[0], arrs[1] ];
			coordinatesArrs[i] = arr;
		}
	}else if (geometryType == "Polygon") {		//面
		for (var i = 0; i < coordinates.length; i++) {
			var py = coordinates[i];
			var coor = [];
			for (var j = 0; j < py.length; j++) {
				var y = py[j][0]; // lng
				var x = py[j][1]; // lat
				var arr = [];
				var arrs = new Array();
				arrs = ctarr(x, y);
				arr = [ arrs[0], arrs[1] ];
				coor[j] = arr;
			}
			coordinatesArrs[i]=coor;
		}
	}else if(geometryType == "MultiPolygon"){	//多面体
		for (var i = 0; i < coordinates.length; i++) {
			var coor = [];
			for (var j = 0; j < coordinates[i].length; j++) {
				var py = coordinates[i][j];
				var coor1 = [];
				for (var n = 0; n < py.length; n++) {
					var y = py[n][0];
					var x = py[n][1];
					var arr = [];
					var arrs = new Array();
					arrs = ctarr(x, y);
					arr = [ arrs[0], arrs[1] ];
					coor1[n] = arr;
				}
				coor[j] = coor1;
			}
			coordinatesArrs[i] = coor;
		}
	}else if(geometryType == "MultiLineString"){	//线集合
		for (var i = 0; i < coordinates.length; i++) {
			var py = coordinates[i];
			var coor = [];
			for (var j = 0; j < py.length; j++) {
				var y = py[j][0];
				var x = py[j][1];
				var arr = [];
				var arrs = new Array();
				arrs = ctarr(x, y);
				arr = [ arrs[0], arrs[1] ];
				coor[j] = arr;
			}
			coordinatesArrs[i] = coor;
		}
	}else if(geometryType == "MultiPoint"){		//点集合
		for (var i = 0; i < coordinates.length; i++) {
			var y = coordinates[i][0];
			var x = coordinates[i][1];
			var arr = [];
			var arrs = new Array();
			arrs = ctarr(x, y);
			arr = [ arrs[0], arrs[1] ];
			coordinatesArrs[i] = arr;
		}
	}
	return coordinatesArrs;
}
// 坐标转换等方法,x坐标以2开头,y坐标以5开头
function ctarr(x, y) {
	var arr = new Array(x, y);
	var acr = L.latLng(arr);
	var catLng = crs.project(acr);
	var arrs = new Array(catLng.x, catLng.y);
	return arrs;
}

controller层的代码:

/**
 * 下载shp文件
 * */
@RequestMapping(value="outShp", method=RequestMethod.POST)
@ResponseBody
public void outShp(HttpServletRequest request, HttpServletResponse response){
	leafletService.outShp(request,response);
}

leafletService中的代码:

/**
 * 下载shp文件
 * */
public void outShp(HttpServletRequest request, HttpServletResponse response){
	 try {
			 JsonMapper jsonMapper = new JsonMapper();
			 List jsonListY = jsonMapper.fromJson(request.getParameter("coordinates"),List.class);
			 GeoToolsUtils gu=new GeoToolsUtils();
			 String downFile = Global.getUserfilesBaseDir("shpfiles","download")+"shapefile.shp";   //未压缩的文件主体
			 File file  = gu.writes(downFile,jsonListY,request.getParameter("arrProperties"),request.getParameter("geometryType"));
			 String filename = file.getName();
			 InputStream fis = new BufferedInputStream(new FileInputStream(file));
			 byte[] buffer = new byte[fis.available()];
			 fis.read(buffer);
			 fis.close();
			 response.reset();
			 // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
			 response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.replaceAll(" ", "").getBytes("utf-8"),"iso8859-1"));
			 response.addHeader("Content-Length", "" + file.length());
			 OutputStream os = new BufferedOutputStream(response.getOutputStream());
			 response.setContentType("application/octet-stream");
			 os.write(buffer);// 输出文件
			 os.flush();
			 os.close();
			 file.delete();
        }catch (Exception e){
            e.printStackTrace();
        }
}

GeoToolsUtils 中的代码

public class GeoToolsUtils {
	
	//投影坐标系(国家2000坐标系)
	private final static String strWKT = "PROJCS[\"CGCS2000_3_Degree_GK_CM_114E\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",114.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]";
	//一个反序列化的类
	private final static JsonMapper jsonMapper = new JsonMapper();
	
	/**
	 * shape文件下载
	 * @param filepath 下载路径
	 * @param jsonListY 坐标
	 * @param jsonListR 属性
	 * @return
	 */
	public File writes(String filepath,List<List> jsonListY,String jsonListR,String geometryType) {  
	    try {  
	    	JsonNode tree = jsonMapper.readTree(jsonListR);
	    	File file = new File(filepath);
	    	Map<String, Serializable> params = new HashMap<>(); 
	    	params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
	    	ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
            Charset charset = Charset.forName("UTF-8");
	    	SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();      	
	    	FeatureWriter<SimpleFeatureType, SimpleFeature>  writer = null;
	    	tb.setName("shapefile");  //设置下载的文件名
	    	ds.setCharset(charset);	  //设置编码
			
			//jsonMapper.fromJson()是反序列化POJO或简单Collection如List<String>的方法
			Map<String,String> fromJsonPr = jsonMapper.fromJson(tree.toString(),HashMap.class);
			switch (geometryType) {
			case "Point":
				tb.add("the_geom", Point.class); 
				break;
			case "LineString":
				tb.add("the_geom", LineString.class); 
				break;
			case "Polygon":
				tb.add("the_geom", Polygon.class); 
				break;
			case "MultiPoint":
				tb.add("the_geom", MultiPoint.class); 
				break;
			case "MultiLineString":
				tb.add("the_geom", MultiLineString.class); 
				break;
			case "MultiPolygon":
				tb.add("the_geom", MultiPolygon.class); 
				break;
			}
			for(String key:fromJsonPr.keySet()){
				tb.add(key, String.class); 
			}
			ds.createSchema(tb.buildFeatureType());  
			if (null==writer){
				writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
			}
			SimpleFeature feature = writer.next(); 
			WKTReader reader = new WKTReader( new GeometryFactory() );
			wktGeo(feature,reader,geometryType,jsonListY,fromJsonPr);
				
	    	writer.write();  
	    	writer.close();
	    	ds.dispose();  
	    	File zips=zipShapeFile(filepath);
	    	file.delete();
	    	return zips;
	    }catch(Exception e) {
	    	e.printStackTrace();
	    }
	    return null;
	} 
	
	public void wktGeo(SimpleFeature feature,WKTReader reader,String type,List<List> jsonListY,Map<String,String> fromJsonPr) {
		/*	POINT (30 10)
		 * 	LINESTRING (30 10, 10 30, 40 40)
		 * 	POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))
		 * 	POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10),(20 30, 35 35, 30 20, 20 30))
		 * 	MULTIPOINT (10 40, 40 30, 20 20, 30 10)
		 * 	MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))
		 * 	MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20)))
		 * 	MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))
		 * */
		String strp="";
		
		try {
			switch (type) {
			case "Point":
				strp += jsonListY.get(0)+" "+jsonListY.get(1);
				Point point = (Point) reader.read("POINT("+strp+")");
				feature.setAttribute("the_geom", point); 
				break;
			case "LineString":
				for (int i = 0; i < jsonListY.size(); i++) {
		    		strp += jsonListY.get(i).get(0)+" "+jsonListY.get(i).get(1);
					if(i != jsonListY.size()-1) strp+=",";
		    	}
				LineString lineString = (LineString) reader.read("LINESTRING("+strp+")");
				feature.setAttribute("the_geom", lineString); 
				break;
			case "Polygon":
				strp="(";
				for (int i = 0; i < jsonListY.size(); i++) {
		    		List<List> list = jsonMapper.fromJson(jsonListY.get(i).toString(),List.class);
		    		if (i>0) strp += ",(";
					for(int j=0; j<list.size(); j++){
						strp += list.get(j).get(0)+" "+list.get(j).get(1);
						if(j != list.size()-1)	strp+=",";
						else strp += ")";
					}
		    	}
				Polygon polygon = (Polygon) reader.read("POLYGON("+strp+")");
	    		feature.setAttribute("the_geom", polygon); 
				break;
			case "MultiPoint":
				for (int i = 0; i < jsonListY.size(); i++) {
		    		strp += jsonListY.get(i).get(0)+" "+jsonListY.get(i).get(1);
					if(i != jsonListY.size()-1)	strp+=",";
		    	}
				MultiPoint multiPoint = (MultiPoint) reader.read("MULTIPOINT("+strp+")");
				feature.setAttribute("the_geom", multiPoint); 
				break;
			case "MultiLineString":
				strp="(";
				for (int i = 0; i < jsonListY.size(); i++) {
					List<List> list = jsonMapper.fromJson(jsonListY.get(i).toString(),List.class);
		    		if (i>0) strp += ",(";
					for(int j=0; j<list.size(); j++){
						strp += list.get(j).get(0)+" "+list.get(j).get(1);
						if(j != list.size()-1)	strp+=",";
						else strp += ")";
					}
				}
				MultiLineString mLineString = (MultiLineString) reader.read("MULTILINESTRING("+strp+")");
				feature.setAttribute("the_geom", mLineString); 
				break;
			case "MultiPolygon":
				strp="((";
				for (int i = 0; i < jsonListY.size(); i++) {
					List<List> list = jsonMapper.fromJson(jsonListY.get(i).toString(),List.class);
		    		if (i>0) strp += ",((";
					for(int j=0; j<list.size(); j++){
						
						if (j>0) strp += ",(";
						List<List> list1 = jsonMapper.fromJson(list.get(j).toString(),List.class);
						for (int n = 0; n < list1.size(); n++) {
							strp += list1.get(n).get(0)+" "+list1.get(n).get(1);
							if(n != list1.size()-1) strp+=",";
							else strp += ")";
						}
						if(j != list.size()-1) strp+=",";
						else strp += ")";
					}
				}
				MultiPolygon mPolygon = (MultiPolygon) reader.read("MULTIPOLYGON("+strp+")");
				feature.setAttribute("the_geom", mPolygon); 
				break;
			}
			for(String key:fromJsonPr.keySet()){
				if (fromJsonPr.get(key) != null) {
					String str = String.valueOf(fromJsonPr.get(key));
					feature.setAttribute(key,str);
				} 
			}
			System.out.println(feature.getAttribute("the_geom"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public File zipShapeFile(String shpPath){
        try{
            File shpFile = new File(shpPath);
            String shpRoot = shpFile.getParentFile().getPath(),
                    _shpName = shpFile.getName(),
                    shpName = _shpName.substring(0, _shpName.lastIndexOf("."));
            String zipPath = shpRoot+File.separator+shpName+".zip";
            File zipFile = new File(zipPath);
            InputStream input = null;
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            // zip的名称为
            zipOut.setComment(shpName);
            String[] shpFiles = new String[]{
                    shpRoot+File.separator+shpName+".dbf",
                    shpRoot+File.separator+shpName+".prj",
                    shpRoot+File.separator+shpName+".shp",
                    shpRoot+File.separator+shpName+".shx",
            };
            for(int i=0;i<shpFiles.length;i++){
            	//获取后缀名为 prj 的文件
            	String string = shpFiles[i].substring(shpFiles[i].lastIndexOf(".") + 1);
            	if ("prj".equals(string)) {
            		FileWriter fw = new FileWriter(shpRoot+File.separator+shpName+".prj");
            		fw.write(strWKT);//往.prj文件中写入投影坐标系
            		fw.flush();
            		fw.close();
				}
                File _file = new File(shpFiles[i]);
                input = new FileInputStream(_file);
                zipOut.putNextEntry(new ZipEntry(_file.getName()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOut.write(temp);
                }
                input.close();
            }
            zipOut.close();
            return zipFile;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

符华-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值