这里只做了点的 , 线,多线 等同理
下面例子中的结果,如图
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.GeometryBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* @author qinlei
* @description geo 工具类
* @date 2022/7/12 17:20
*/
public class GeoUtils {
public static void main(String[] args) throws IOException {
List<Map<String,Object>> propertiesList = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("coordinates","108.1201,34.1245");
map.put("id","asd2154512");
map.put("date",new Date());
propertiesList.add(map);
Map<String,Object> map2 = new HashMap<>();
map2.put("coordinates","108.9201,34.5245");
map2.put("id","bsd2154512");
map2.put("date",new Date());
propertiesList.add(map2);
Map<String,Object> map3 = new HashMap<>();
map3.put("coordinates","108.9951,34.1905");
map3.put("id","kdf2154512");
map3.put("date",new Date());
propertiesList.add(map3);
String point = generateGeoJson("POINT", propertiesList, new ByteArrayOutputStream());
System.out.println(point);
}
public static String generateGeoJson(String type,
List<Map<String,Object>> propertiesList,
ByteArrayOutputStream output) throws IOException {
SimpleFeatureType featureType = createFeatureType(propertiesList.get(0));
FeatureJSON featureJson = generateFeatureJson(featureType, false);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("fid-"+System.currentTimeMillis(), featureType);
for (Map<String, Object> map : propertiesList) {
SimpleFeatureType featureType1 = featureBuilder.getFeatureType();
featureBuilder.add(generateGeometry(type,map.get("coordinates")));
//这里仅仅不想再properties中展示坐标
map.remove("coordinates");
map.forEach((k,v)-> featureBuilder.set(k,v));
SimpleFeature feature = featureBuilder.buildFeature("fid-"+System.currentTimeMillis());
featureCollection.add(feature);
}
featureJson.writeFeatureCollection(featureCollection, output);
return output.toString(StandardCharsets.UTF_8.name());
}
private static FeatureJSON generateFeatureJson(SimpleFeatureType featureType, boolean includeCrs) {
GeometryJSON geometryJson = new GeometryJSON(6);
FeatureJSON featureJson = new FeatureJSON(geometryJson);
featureJson.setFeatureType(featureType);
//生成feature的bbox
featureJson.setEncodeFeatureBounds(true);
featureJson.setEncodeFeatureCRS(includeCrs);
//生成featureCollection的bbox
featureJson.setEncodeFeatureCollectionBounds(true);
featureJson.setEncodeFeatureCollectionCRS(includeCrs);
return featureJson;
}
private static Geometry generateGeometry(String type,Object coordinates){
//构建geometry
final GeometryBuilder geometryBuilder = new GeometryBuilder();
Geometry geometry;
switch (type) {
case "POINT":
String[] split = String.valueOf(coordinates).split(",");
geometry = geometryBuilder.point(Double.valueOf(split[0]), Double.valueOf(split[1]));
break;
/*case "LINESTRING":
geometry = geometryBuilder.lineString(coordinates.stream()
.flatMap(Tuple::stream)
.mapToDouble(coordinate -> (Double) coordinate)
.toArray());
break;
case "MULTILINESTRING":
geometry = geometryBuilder.lineString(coordinates.stream()
.flatMap(Tuple::stream)
.mapToDouble(coordinate -> (Double) coordinate)
.toArray());
break;*/
default:
throw new IllegalArgumentException(String.format("======> %s is not currently supported.", type));
}
return geometry;
}
private static SimpleFeatureType createFeatureType(Map<String,Object> properties) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Mapbox-position");
builder.setCRS(DefaultGeographicCRS.WGS84);
// 在feature中添加geometry
builder.add("geometry", Geometry.class);
properties.forEach((k,v)->{
//仅仅不想再properties中展示坐标
if(!"coordinates".equals(k)){
builder.add(k,Object.class);
}
//下面这个可以具体描述每个字段的类型
/*if(v instanceof String){
builder.add(k,String.class);
}else if(v instanceof Integer){
builder.add(k,Integer.class);
}else if(v instanceof Date){
builder.add(k,Date.class);
}else if(v instanceof Float){
builder.add(k,Float.class);
}else if(v instanceof Integer){
builder.add(k,Integer.class);
}else if(v instanceof Double){
builder.add(k,Double.class);
}else {
builder.add(k,Object.class);
}*/
});
return builder.buildFeatureType();
}
}
在码的过程中理解了FeatureType
, FeatureType
的作用是在FeatureCollection
中预留每个字段的位置,提前开辟空间。
个人正在整理项目中用到的geotools,抽空本人会封装起来。 https://gitee.com/qlanto/geotools-kit