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

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> 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> readFile(String shapePath, String prjPath) {
        List> list = new ArrayList>();
        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 it = feature.getProperties().iterator();
                Map map = new HashMap();
                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

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内的测试方法,即可获取如下结果。

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

方法里面用到一些jar包,用maven无法引用,需要下载进行引入,下面是maven引入本地jar包,这里面有一些用不到,我一块引进来了。

   
        
            org.geotools
            gt-shapefile
            19.2
            system
            ${project.basedir}/lib/gt-shapefile-19.2.jar
        
        
            org.ejml
            ejml-ddense
            0.39
            system
            ${project.basedir}/lib/ejml-ddense-0.32.jar
        
        
            org.ejml
            ejml-core
            0.39
            system
            ${project.basedir}/lib/ejml-core-0.39.jar
        
        
            org.geotools
            gt-opengis
            19.2
            system
            ${project.basedir}/lib/gt-opengis-19.2.jar
        

        
            org.geotools
            gt-data
            19.2
            system
            ${project.basedir}/lib/gt-data-19.2.jar
        

        
            org.geotools
            gt-api
            19.2
            system
            ${project.basedir}/lib/gt-api-19.2.jar
        

        
            org.geotools
            gt-main
            19.2
            system
            ${project.basedir}/lib/gt-main-19.2.jar
        

        
            org.geotools
            gt-metadata
            19.2
            system
            ${project.basedir}/lib/gt-metadata-19.2.jar
        

        
            org.geotools
            gt-referencing
            19.2
            system
            ${project.basedir}/lib/gt-referencing-19.2.jar
        

        
            org.geotools
            gt-geojson
            19.2
            system
            ${project.basedir}/lib/gt-geojson-19.2.jar
        
        
        
            com.google.code.gson
            gson
            2.8.5
        
        
            org.json.simple
            json-simple
            1.1
            system
            ${project.basedir}/lib/json-simple-1.1.jar
        
        
            javax.measure
            jsr-275-1.0-beta
            2
            system
            ${project.basedir}/lib/jsr-275-1.0-beta-2.jar
        
        
            com.vividsolutions
            jts
            1.13
            system
            ${project.basedir}/lib/jts-1.13.jar
        
        
        
            com.amazonaws
            aws-java-sdk
            1.5.5
        
        
            org.projectlombok
            lombok
            1.18.4
            provided
        
        
            cn.hutool
            hutool-all
            5.8.0
        
        

            com.alibaba

            fastjson

            2.0.12

        

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

我已上传下载链接https://download.csdn.net/download/qq_38382365/88625655

你可能感兴趣的:(java,开发语言,spring,boot,算法)