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

Posted 爱是与世界平行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换相关的知识,希望对你有一定的参考价值。

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("\\r\\n");
				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+"\\t"+bbDistance+"\\t"+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()+"\\n"+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("\\n" +
                "                \\"type\\": \\"LineString\\",\\n" +
                "                \\"coordinates\\": [\\n" +
                "                    [\\n" +
                "                        120.6584555,\\n" +
                "                        30.45144\\n" +
                "                    ],\\n" +
                "                    [\\n" +
                "                        120.1654515,\\n" +
                "                        30.54848\\n" +
                "                    ]\\n" +
                "                ]\\n" +
                "            "));

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”]

以上是关于GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换的主要内容,如果未能解决你的问题,请参考以下文章

Java Gson 实现 Json 数据的生成与解析

将 geoJson 数据转换为 sql server 空间数据类型(GIS)

Qt之JSON生成与解析

[javaEE]Java中JSON的简单使用与前端解析

java使用jackson生成和解析JSON

Java基础-JSON解析