• GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换


    环境

    gt-geojson-14.2.jar,json-simple-1.1.1.jar,jts-1.8.jar
    

    一、wkt格式的geometry转成json格式

    public String evaluate(String wkt) {
    
            String ret = null;
            try {
                Geometry geometry = reader.read(wkt);
                StringWriter writer = new StringWriter();
                GeometryJSON g = new GeometryJSON();
                g.write(geometry, writer);
                ret = writer.toString();
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
            return ret;
        }
    

    二、json格式转wkt格式

    public String evaluate(String geoJson) {
            String ret = null;
            GeometryJSON gjson = new GeometryJSON();
            Reader reader = new StringReader(geoJson);
            try {
                Geometry geometry = gjson.read(reader);
                ret = geometry.toText();
            } catch (IOException e) {
                LOGGER.error(e.getMessage(), e);
            }
            return ret;
        }
    
    

    三、json格式的数据进行解析

    数据格式如下:

    {
      "_id" : "b454e650cb1a4fa4a2f2bd6899fbfa73",
      "bb" : "116.2451019,39.8486099,116.2451019,39.8486099",
      "pts" : [{
          "1" : 0,
          "2" : 39.8486099,
          "3" : 116.2451019,
          "4" : 0.0,
          "5" : 0.0,
          "6" : "2012-03-07 14:25:08",
          "7" : "2012-03-07 14:25:10",
          "8" : "2",
          "9" : 0.0,
          "10" : 1
        }, {
          "1" : 1,
          "2" : 39.8486099,
          "3" : 116.2451019,
          "4" : 0.0,
          "5" : 0.0,
          "6" : "2012-03-07 14:25:16",
          "7" : "2012-03-07 14:25:17",
          "8" : "1",
          "9" : 0.0,
          "10" : 1
        }, {
          "1" : 2,
          "2" : 39.8486099,
          "3" : 116.2451019,
          "4" : -1.0,
          "5" : 0.0,
          "6" : "2012-03-07 14:25:18",
          "7" : "2012-03-07 14:25:20",
          "8" : "1",
          "9" : 0.0,
          "10" : 1
        }]
    }
    

    获取“_id”值和“bb”属性值(两点的经纬度坐标),获取“pts”属性中第一个标签6的值(起始时间)和最后一个标签7的属性值(终止时间),并根据经纬度计算两点之间的距离,根据起始时间和终止时间计算其时间差,得到每个“_id”的对应的距离和时间差

    private final double PI = 3.1415926; //圆周率
    	private final static double earthRadius = 6371; //地球半径,单位为KM
    	
    	public static void parseJson(BufferedReader bufferedReader) 
    			throws IOException, ParseException, java.text.ParseException{
    		
    		String line = ""; //一行一行的形式读取文件
    		String[] pts6FirstTime =null;//第一个坐标点标签6的时间
    		String pts6Time ="";
    		String ptsTime7 = "";
    		String reslut = ""; //计算最终结果
    		double betweenTime = 0.0d;//轨迹点之间的时间差,以小时(h)为单位
    		
    		//longitude1、longitude2、dimension1、dimension2分别为经度坐标和维度坐标
    		double longitude1 = 0.0d;
    		double dimension1 = 0.0d;
    		
    		double longitude2 = 0.0d;
    		double dimension2 = 0.0d; 
    		
    		//设置时间格式
    		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		
    		//创建json解析对象
    		JSONParser jsonParser = new JSONParser();
    		
    		//创建一个distanceAndTime对象
    		DistanceAndTime distanceAndTime = new DistanceAndTime();
    		
    		while((line = bufferedReader.readLine())!=null){
    			//开始解析
    			JSONObject jsonObject = (JSONObject)jsonParser.parse(line);
    			
    			String _id = (String) jsonObject.get("_id");//得到轨迹的id号
    			
    			String bb = (String) jsonObject.get("bb");//得到轨迹的经纬度坐标bb
    			//经纬度坐标是以","进行分割的
    			String[] longitudeDismension = bb.split(",");
    			//Double.valueOf()把string类型转换为double类型
    			longitude1 = Double.valueOf(longitudeDismension[0]);
    			dimension1 = Double.valueOf(longitudeDismension[1]);
    			
    			longitude2 = Double.valueOf(longitudeDismension[2]);
    			dimension2 = Double.valueOf(longitudeDismension[3]);
    			
    			//计算具有经纬度的两坐标间的距离
    			double bbDistance = distanceAndTime.
    					getDistance(longitude1, dimension1, longitude2, dimension2);
    			
    			//解析pts中的内容
    			JSONArray ptsjsonArray = (JSONArray)jsonObject.get("pts");
    			Iterator iterator = ptsjsonArray.iterator();
    			
    			//解析pts中标签6的内容,并得到第一个标签6的内容
    			while(iterator.hasNext()){
    				JSONObject pts6JSONObject = (JSONObject)iterator.next();
    				pts6Time = pts6JSONObject.get("6").toString();
    				pts6FirstTime = pts6Time.split("
    ");
    				break;//对于标签6的时间,只要第一个时间
    			}
    			
    			//解析pts中标签7的内容,并得到最后一个标签7的内容
    			while(iterator.hasNext()){
    				JSONObject pts7jsonobject = (JSONObject)iterator.next();
    				ptsTime7 = pts7jsonobject.get("7").toString();
    			}
    			
    			//计算轨迹的时间差,单位为小时(H)
    			Date date1 = dateFormat.parse(ptsTime7);
    			Date date2 = dateFormat.parse(pts6FirstTime[0]);
    			betweenTime = (date1.getTime()-date2.getTime())/1000.0/3600.0;
    			
    			reslut = _id+"	"+bbDistance+"	"+betweenTime;
    			writeToLocal(reslut);
    //			System.out.println(reslut);
    		}
    		
    	}
    	
    	//已知经纬度的轨迹点,计算两个轨迹点之间的距离,单位为KM
    	public double getDistance(double longitude1,double dimension1,double longitude2,double dimension2){
    		double x,y,distance;
    		x = (longitude1 - longitude2)*PI*earthRadius*
    				Math.cos(((dimension1+dimension2)/2)*PI/180)/180;
    		y = (dimension1-dimension2)*PI*earthRadius/180;
    		distance = Math.hypot(x, y);
    		return distance;
    	}
    	
    	//计算结果输出
    	public static void writeToLocal(String string) throws IOException{
    		File outFile = new File("D://0820--Study//轨迹点数据//result.json");
    		if (!outFile.exists()) {
    			outFile.createNewFile();
    		}
    		
    		//FileOutputStream设置为true,是为了后一条结果记录覆盖前一条结果记录
    		FileOutputStream fileOutputStream = new FileOutputStream(outFile,true);
    		OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
    		BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
    		bufferedWriter.write(string);
    		bufferedWriter.newLine();
    		bufferedWriter.flush();
    		
    		bufferedWriter.close();
    		outputStreamWriter.close();
    		fileOutputStream.close();
    	}
    

    四、Java读写geojson

    /** 读 **/
    public Map<Integer, SiteEntity> getSiteMap() {
            Map<Integer, SiteEntity> map = new HashMap<Integer, SiteEntity>();
            URL dataUrl = this.getClass().getClassLoader().getResource("public\station.json");  //  259
            try{
                BufferedReader br =new BufferedReader(new FileReader(new File(dataUrl.toURI())));
                String s = null;
                while((s = br.readLine()) != null){  // s 为原生的json串
    //                System.out.println("00=="+s);
                    JSONObject jo = new JSONObject(s); // 创建一个包含原始json串的json对象
                    JSONArray features = jo.getJSONArray("features"); //找到features的json数组
                    for (int i = 0; i < features.length(); i++) {
                        SiteEntity siteEntity = new SiteEntity();
                        JSONObject info = features.getJSONObject(i); // 获得features的第i个对象
    
                        JSONObject geometry = info.getJSONObject("geometry");
                        JSONObject properties = info.getJSONObject("properties");
    
                        siteEntity.setSite_stano(properties.getString("stano"));  // 获得站名
    
                        List list  = geometry.getJSONArray("coordinates").toList();  // 获得经纬度
                        siteEntity.setSite_longitude(Double.parseDouble(list.get(0).toString()));
                        siteEntity.setSite_latitude(Double.parseDouble(list.get(1).toString()));
    //                    System.out.println(siteEntity.getSite_longitude()+"
    "+siteEntity.getSite_latitude());
                        map.put(i,siteEntity);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            return map;
        }
    
    
    /**写**/
    public void jsonOutPut(Map map) {
            ObjectMapper mapper = new ObjectMapper();
            try{
                mapper.writeValue(new File("D:/river-site.json"), map);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    

    五、geotools读取shp文件

    5.1 pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.jjxliu.geotools</groupId>
      <artifactId>geotools_t1</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>geotools_t1</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <geotools.version>20-SNAPSHOT</geotools.version>
      </properties>
    <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-shapefile</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-swing</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
      			<groupId>org.geotools</groupId>
      			<artifactId>gt-jdbc</artifactId>
      			<version>${geotools.version}</version>
    		</dependency>
            <dependency>
       			<groupId>org.geotools.jdbc</groupId>
       			<artifactId>gt-jdbc-postgis</artifactId>
       			<version>${geotools.version}</version>
     		</dependency>
     	
     		<dependency>
       			<groupId>org.geotools</groupId>
       			<artifactId>gt-epsg-hsql</artifactId>
       			<version>${geotools.version}</version>
     		</dependency>
     		
        </dependencies>
         <repositories>
            <repository>
                <id>maven2-repository.dev.java.net</id>
                <name>Java.net repository</name>
                <url>http://download.java.net/maven/2</url>
            </repository>
            <repository>
                <id>osgeo</id>
                <name>Open Source Geospatial Foundation Repository</name>
                <url>http://download.osgeo.org/webdav/geotools/</url>
            </repository>
            <repository>
              <snapshots>
                <enabled>true</enabled>
              </snapshots>
              <id>boundless</id>
              <name>Boundless Maven Repository</name>
              <url>http://repo.boundlessgeo.com/main</url>
            </repository>
        </repositories>
         <build>
            <plugins>
                <plugin>
                    <inherited>true</inherited>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    5.2 读取shp文件

    public static SimpleFeatureCollection  readShp(String path ){
    		return readShp(path, null);
    		
    	}
     
    	public static SimpleFeatureCollection  readShp(String path , Filter filter){
    	  
    		SimpleFeatureSource  featureSource = readStoreByShp(path);
    		   
    		if(featureSource == null) return null;
              
    		try {
    			return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures() ;
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} 
             
             return null ;
    	}
    	
    	public static  SimpleFeatureSource readStoreByShp(String path ){
    		 
    		File file = new File(path);
        	 
    		FileDataStore store;
    		SimpleFeatureSource featureSource = null;
    		try {
    			store = FileDataStoreFinder.getDataStore(file);
    			 ((ShapefileDataStore) store).setCharset(Charset.forName("UTF-8"));
    			featureSource = store.getFeatureSource();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
             
             return featureSource ;
    	}
    

    测试一段读取的代码,打印所有读取到的simplefeature

    String path1 = "G:/work/china_map/shp/BOUNT_poly.shp" ;
    		
    		//读取shp
    		SimpleFeatureCollection  colls1 = readShp(path1);
    		//拿到所有features
    		SimpleFeatureIterator iters = colls1.features();
    		//遍历打印
    		while(iters.hasNext()){
    			SimpleFeature sf = iters.next();
    			
    			System.out.println(sf.getID() + " , " + sf.getAttributes());
    			
    		}
    

    在这里插入图片描述

    六、Geotools中Geometry对象与GeoJson的相互转换

    6.1 pom.xml

    <geotools.version>17.1</geotools.version>
    <!-- for geotools begin -->
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-geojson</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.geotools/gt-main -->
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-main</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-api</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-opengis</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-data</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-referencing</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <!--for geotools end-->
    

    import包

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.vividsolutions.jts.geom.*;
    import com.vividsolutions.jts.geom.Point;
    import com.vividsolutions.jts.io.ParseException;
    import com.vividsolutions.jts.io.WKTReader;
    import com.vividsolutions.jts.operation.linemerge.LineMerger;
    import org.geotools.data.DataUtilities;
    import org.geotools.feature.SchemaException;
    import org.geotools.feature.simple.SimpleFeatureBuilder;
    import org.geotools.geojson.feature.FeatureJSON;
    import org.geotools.geojson.geom.GeometryJSON;
    import org.geotools.geometry.jts.JTSFactoryFinder;
    import org.opengis.feature.simple.SimpleFeature;
    import org.opengis.feature.simple.SimpleFeatureType;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.io.IOException;
    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.*;
    

    Geometry的子类主要有Point, LineString和Polygon. 基本操作类似。所以此处以LineString为例说明:

    6.2 LineString–>geojson

    
    // 由wkt字符串构造LineString对象
    WKTReader reader = new WKTReader( geometryFactory );
    LineString lineString = (LineString)reader.read("LINESTRING (254058.76074485347 475001.2186020431, 255351.04293761664 474966.9279243938)");
    // 设置保留6位小数,否则GeometryJSON默认保留4位小数
    GeometryJSON geometryJson = new GeometryJSON(6);
    StringWriter writer = new StringWriter();
    geometryJson.write(lineString, writer);
    System.out.println(writer.toString());
    writer.close();
    

    6.3 geojson–>LineString

    LineString lineString = (LineString) geometryJson.read(new StringReader("{
    " +
                    "                "type": "LineString",
    " +
                    "                "coordinates": [
    " +
                    "                    [
    " +
                    "                        120.6584555,
    " +
                    "                        30.45144
    " +
                    "                    ],
    " +
                    "                    [
    " +
                    "                        120.1654515,
    " +
                    "                        30.54848
    " +
                    "                    ]
    " +
                    "                ]
    " +
                    "            }"));
    

    geojson还定义了带属性的Feature和表示Geometry对象集合的FeatureCollection,构造方法更加复杂,写两个示例备忘吧。

    6.4 LineString转Feature

    // geometry是必须的,其他属性可根据需求自定义,但是支持的类型有限,例如这个版本中double是不支持的,只支持float
    final SimpleFeatureType TYPE = DataUtilities.createType("Link",
                    "geometry:LineString," + // <- the geometry attribute: Point type
                            "gid:String," +   // <- a String attribute
                            "direction:Integer," +   // a number attribute
                            "orientation:Integer"
            );
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    WKTReader reader = new WKTReader( geometryFactory );
    FeatureJSON fjson = new FeatureJSON();
    LineString lineString = (LineString)reader.read("LINESTRING (254058.76074485347 475001.2186020431, 255351.04293761664 474966.9279243938)");
    // 按照TYPE中声明的顺序为属性赋值就可以,其他方法我暂未尝试
    featureBuilder.add(lineString);
    featureBuilder.add("123456");
    featureBuilder.add(2);
    featureBuilder.add(0);
    SimpleFeature feature = featureBuilder.buildFeature(null);
    StringWriter writer = new StringWriter();
    fjson.writeFeature(feature, writer);
    System.out.println(writer.toString());
    

    执行结果如下:

    {“type”:”Feature”,”geometry”:{“type”:”LineString”,”coordinates”:[[254058.7607,475001.2186],[255351.0429,474966.9279]]},”properties”:{“gid”:”123456”,”direction”:2,”orientation”:0},”id”:”fid–5b8f258_15e04bda4b8_-8000”}
    

    6.5 Feature转LineString

    6.6 LineString转FeatureCollection

    String[] WKTS = { "LINESTRING (255351.04293761664 474966.9279243938, 255529.29662365236 474272.4599921228)",
                    "LINESTRING (255529.29662365236 474272.4599921228, 256166.05830998957 473979.44920198264)"};
    final SimpleFeatureType TYPE = DataUtilities.createType("Link",
                    "geometry:LineString," + // <- the geometry attribute: Point type
                            "gid:String," +   // <- a String attribute
                            "direction:Integer," +   // a number attribute
                            "orientation:Integer"
    );
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    WKTReader reader = new WKTReader( geometryFactory );
    FeatureJSON fjson = new FeatureJSON();
    List<SimpleFeature> features = new ArrayList<>();
    SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
    for (String wkt : WKTS) {
        LineString lineString = (LineString)reader.read(wkt);
        featureBuilder.add(lineString);
        featureBuilder.add("123456");
        featureBuilder.add(2);
        featureBuilder.add(1);
        SimpleFeature feature = featureBuilder.buildFeature(null);
        features.add(feature);
    }
    StringWriter writer = new StringWriter();
    fjson.writeFeatureCollection(collection, writer);
    System.out.println(writer.toString());
    

    打印结果如下:

    {“type”:”FeatureCollection”,”features”:[{“type”:”Feature”,”geometry”:{“type”:”LineString”,”coordinates”:[[255351.0429,474966.9279],[255529.2966,474272.46]]},”properties”:{“gid”:”123456”,”direction”:2,”orientation”:1},”id”:”fid-67c46b85_15e0778dd81_-8000”},{“type”:”Feature”,”geometry”:{“type”:”LineString”,”coordinates”:[[255529.2966,474272.46],[256166.0583,473979.4492]]},”properties”:{“gid”:”123456”,”direction”:2,”orientation”:1},”id”:”fid-67c46b85_15e0778dd81_-7fff”}]}
    
  • 相关阅读:
    性能分析
    thymeleaf和spring的整合
    Java中二叉树的建立
    面试题
    (转)structs2的相关配置问题
    ==与equal()的区别
    java的基本类型和其包装类
    Ajax调用返回json数组,对象 (JSONArray.fromObject)
    (转)在JSP中调用JAVA类和使用JavaBean有什么区别?
    用log4j查看详细错误信息
  • 原文地址:https://www.cnblogs.com/aixing/p/13327381.html
Copyright © 2020-2023  润新知