1.新建ShapeUtils工具类解析shp文件
package com.ruoyi.info.geotoolsUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 解析shp文件
* @author lsyong
*
*/
public class ShapeUtils {
private static final Logger logger = LoggerFactory.getLogger(ShapeUtils.class);
/**
* 测试
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String shpFilePath = "F:\\1water\\dasihe\\矢量图\\划界矢量图.shp";
long time = System.currentTimeMillis();
List<Map<String,Object>> readFile = readFile(shpFilePath, null);
long time2 = System.currentTimeMillis();
System.out.println("耗时:" + (time2 - time));
System.out.println(readFile);
}
/**
* 读取shp文件
*
* @Description
* @author gxx
* @date: 2019年7月3日 上午9:33:43
*/
public static List<Map<String, Object>> readFile(String shapePath, String prjPath) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
ShapefileDataStore dataStore = null;
try {
dataStore = (ShapefileDataStore) factory.createDataStore(new File(shapePath).toURI().toURL());
if (dataStore != null) {
dataStore.setCharset(Charset.forName("GB2312"));
}
SimpleFeatureSource featureSource = dataStore.getFeatureSource();
SimpleFeatureIterator itertor = featureSource.getFeatures().features();
while (itertor.hasNext()) {
SimpleFeature feature = itertor.next();
Iterator<Property> it = feature.getProperties().iterator();
Map<String, Object> map = new HashMap<String, Object>();
while (it.hasNext()) {
Property pro = it.next();
if("the_geom".equals(String.valueOf(pro.getName()))) {
map.put(String.valueOf(pro.getName()), CoordConverter.multipolygontoline(String.valueOf(pro.getValue())));
} else {
map.put(String.valueOf(pro.getName()), String.valueOf(pro.getValue()));
}
}
list.add(map);
}
itertor.close();
return list;
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if(dataStore != null) {
dataStore.dispose();
}
}
return null;
}
}
2.新建CoordConverter坐标转换
package com.ruoyi.info.geotoolsUtils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author lsyong
*/
public class CoordConverter {
private static final Logger logger = LoggerFactory.getLogger(CoordConverter.class);
/**
* MULTILINESTRING转成天地图用的线
* @param multipolygon
* @return
*/
public static String multipolygontoline(String multipolygon){
if(null==multipolygon||multipolygon==""){
return null;
}
multipolygon=multipolygon.replaceAll("MULTILINESTRING ","").replaceAll("\\(","").replaceAll("\\)","");
String[] a=multipolygon.split(", ");
JSONArray line = new JSONArray();
JSONObject str = new JSONObject();
JSONArray postion = new JSONArray();
for(int i=0;i<a.length;i++){
String[] b=a[i].split(" ");
String p=xytolatlonUtil.xytolatlon1(Double.parseDouble(b[1]),Double.parseDouble(b[0]),117);
postion.add(p);
}
str.put("postion",postion);
str.put("weight",9);//线宽
str.put("color","#f58220");//颜色
line.add(str);
return line.toString();
}
}
3.坐标段位转换 xytolatlonUtil
package com.ruoyi.info.geotoolsUtils;
public class xytolatlonUtil {
public static void main(String[] args) {
xytolatlon(4073382.472,501680.246,117);
}
/**
*
* @param X 点位坐标X
* @param Y 点位坐标Y
* @param L0 L0参数为中央子午线的经线值
* @return
*/
public static double [] xytolatlon(double X, double Y ,double L0) {
double lat ,lon;
Y-=500000;
double [] result = new double[2];
double iPI = 0.0174532925199433;//pi/180
double a = 6378137.0; //长半轴 m
double b = 6356752.31414; //短半轴 m
double f = 1/298.257222101;//扁率 a-b/a
double e = 0.0818191910428; //第一偏心率 Math.sqrt(5)
double ee = Math.sqrt(a*a-b*b)/b; //第二偏心率
double bf = 0; //底点纬度
double a0 = 1+(3*e*e/4) + (45*e*e*e*e/64) + (175*e*e*e*e*e*e/256) + (11025*e*e*e*e*e*e*e*e/16384) + (43659*e*e*e*e*e*e*e*e*e*e/65536);
double b0 = X/(a*(1-e*e)*a0);
double c1 = 3*e*e/8 +3*e*e*e*e/16 + 213*e*e*e*e*e*e/2048 + 255*e*e*e*e*e*e*e*e/4096;
double c2 = 21*e*e*e*e/256 + 21*e*e*e*e*e*e/256 + 533*e*e*e*e*e*e*e*e/8192;
double c3 = 151*e*e*e*e*e*e*e*e/6144 + 151*e*e*e*e*e*e*e*e/4096;
double c4 = 1097*e*e*e*e*e*e*e*e/131072;
bf = b0 + c1*Math.sin(2*b0) + c2*Math.sin(4*b0) +c3*Math.sin(6*b0) + c4*Math.sin(8*b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...
double tf = Math.tan(bf);
double n2 = ee*ee*Math.cos(bf)*Math.cos(bf); //第二偏心率平方成bf余弦平方
double c = a*a/b;
double v=Math.sqrt(1+ ee*ee*Math.cos(bf)*Math.cos(bf));
double mf = c/(v*v*v); //子午圈半径
double nf = c/v;//卯酉圈半径
//纬度计算
lat=bf-(tf/(2*mf)*Y)*(Y/nf) * (1-1/12*(5+3*tf*tf+n2-9*n2*tf*tf)*(Y*Y/(nf*nf))+1/360*(61+90*tf*tf+45*tf*tf*tf*tf)*(Y*Y*Y*Y/(nf*nf*nf*nf)));
//经度偏差
lon=1/(nf*Math.cos(bf))*Y -(1/(6*nf*nf*nf*Math.cos(bf)))*(1+2*tf*tf +n2)*Y*Y*Y + (1/(120*nf*nf*nf*nf*nf*Math.cos(bf)))*(5+28*tf*tf+24*tf*tf*tf*tf)*Y*Y*Y*Y*Y;
result[0] =retain6(lat/iPI);
result[1] =retain6(L0+lon/iPI);
System.out.println(result[1]+","+result[0]);
return result;
}
/**
*
* @param X 点位坐标X
* @param Y 点位坐标Y
* @param L0 L0参数为中央子午线的经线值
* @return
*/
public static String xytolatlon1(double X, double Y ,double L0) {
double lat ,lon;
Y-=500000;
//double [] result = new double[2];
double iPI = 0.0174532925199433;//pi/180
double a = 6378137.0; //长半轴 m
double b = 6356752.31414; //短半轴 m
double f = 1/298.257222101;//扁率 a-b/a
double e = 0.0818191910428; //第一偏心率 Math.sqrt(5)
double ee = Math.sqrt(a*a-b*b)/b; //第二偏心率
double bf = 0; //底点纬度
double a0 = 1+(3*e*e/4) + (45*e*e*e*e/64) + (175*e*e*e*e*e*e/256) + (11025*e*e*e*e*e*e*e*e/16384) + (43659*e*e*e*e*e*e*e*e*e*e/65536);
double b0 = X/(a*(1-e*e)*a0);
double c1 = 3*e*e/8 +3*e*e*e*e/16 + 213*e*e*e*e*e*e/2048 + 255*e*e*e*e*e*e*e*e/4096;
double c2 = 21*e*e*e*e/256 + 21*e*e*e*e*e*e/256 + 533*e*e*e*e*e*e*e*e/8192;
double c3 = 151*e*e*e*e*e*e*e*e/6144 + 151*e*e*e*e*e*e*e*e/4096;
double c4 = 1097*e*e*e*e*e*e*e*e/131072;
bf = b0 + c1*Math.sin(2*b0) + c2*Math.sin(4*b0) +c3*Math.sin(6*b0) + c4*Math.sin(8*b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...
double tf = Math.tan(bf);
double n2 = ee*ee*Math.cos(bf)*Math.cos(bf); //第二偏心率平方成bf余弦平方
double c = a*a/b;
double v=Math.sqrt(1+ ee*ee*Math.cos(bf)*Math.cos(bf));
double mf = c/(v*v*v); //子午圈半径
double nf = c/v;//卯酉圈半径
//纬度计算
lat=bf-(tf/(2*mf)*Y)*(Y/nf) * (1-1/12*(5+3*tf*tf+n2-9*n2*tf*tf)*(Y*Y/(nf*nf))+1/360*(61+90*tf*tf+45*tf*tf*tf*tf)*(Y*Y*Y*Y/(nf*nf*nf*nf)));
//经度偏差
lon=1/(nf*Math.cos(bf))*Y -(1/(6*nf*nf*nf*Math.cos(bf)))*(1+2*tf*tf +n2)*Y*Y*Y + (1/(120*nf*nf*nf*nf*nf*Math.cos(bf)))*(5+28*tf*tf+24*tf*tf*tf*tf)*Y*Y*Y*Y*Y;
return retain61(lat/iPI)+","+retain61(L0+lon/iPI);
}
private static double retain6(double num) {
String result = String.format("%.6f", num);
return Double.valueOf(result);
}
private static String retain61(double num) {
return String.format("%.6f", num);
}
}
运行ShapeUtils内的测试方法,即可获取如下结果。
方法里面用到一些jar包,用maven无法引用,需要下载进行引入,下面是maven引入本地jar包,这里面有一些用不到,我一块引进来了。
<!-- shp解析-->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-shapefile-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-ddense</artifactId>
<version>0.39</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ejml-ddense-0.32.jar</systemPath>
</dependency>
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-core</artifactId>
<version>0.39</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ejml-core-0.39.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-opengis-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-data</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-data-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-api</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-api-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-main-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-metadata</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-metadata-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-referencing-19.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>19.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gt-geojson-19.2.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.json.simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/json-simple-1.1.jar</systemPath>
</dependency>
<dependency>
<groupId>javax.measure</groupId>
<artifactId>jsr-275-1.0-beta</artifactId>
<version>2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jsr-275-1.0-beta-2.jar</systemPath>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jts-1.13.jar</systemPath>
</dependency>
<!-- shp解析-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.12</version>
</dependency>
我已上传下载链接https://download.csdn.net/download/qq_38382365/88625655