Java .shp文件解析转换成地图可用的经纬度格式

2023-12-13 18:59:01

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

文章来源:https://blog.csdn.net/qq_38382365/article/details/134972439
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。