package com.se.simu.helper;
|
|
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.JSONObject;
|
import com.se.simu.domain.SeField;
|
import com.se.simu.domain.SeLayer;
|
import lombok.extern.slf4j.Slf4j;
|
import org.gdal.ogr.*;
|
|
import java.sql.Timestamp;
|
import java.time.LocalDateTime;
|
import java.util.List;
|
import java.util.Vector;
|
|
/**
|
* ShapeFile帮助类
|
*
|
* @author WWW
|
* @date 2024-09-13
|
*/
|
@Slf4j
|
@SuppressWarnings("ALL")
|
public class ShpHelper {
|
private static Vector<String> options;
|
|
public static Vector<String> getOptions() {
|
if (null == options) {
|
options = new Vector<>();
|
options.add("ENCODING=UTF-8");
|
}
|
|
return options;
|
}
|
|
public static boolean createShp(String filePath, SeLayer seLayer) {
|
Driver driver = null;
|
DataSource dataSource = null;
|
Layer layer = null;
|
try {
|
driver = ogr.GetDriverByName("ESRI shapefile");
|
if (null == driver) return false;
|
|
dataSource = driver.CreateDataSource(filePath, null);
|
if (null == dataSource) return false;
|
|
int geoType = getGeometryType(seLayer.getQueryType());
|
layer = dataSource.CreateLayer(FileUtil.getName(filePath), seLayer.getDb().getSpatialReference(), geoType, getOptions());
|
if (null == layer) return false;
|
|
createLayerFields(layer, seLayer.getFields());
|
|
FeatureDefn featureDefn = layer.GetLayerDefn();
|
for (int i = 0, c = seLayer.getData().size(); i < c; i++) {
|
Feature f = new Feature(featureDefn);
|
JSONObject data = seLayer.getData().getJSONObject(i).getJSONObject("properties");
|
setFeatureData(f, seLayer.getFields(), data);
|
|
JSONObject geom = seLayer.getData().getJSONObject(i).getJSONObject("geometry");
|
Geometry g = createGeometry(seLayer, geom);
|
f.SetGeometry(g);
|
|
layer.CreateFeature(f);
|
}
|
|
return true;
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
return false;
|
} finally {
|
GdalHelper.delete(layer, dataSource, driver);
|
}
|
}
|
|
private static void setFeatureData(Feature f, List<SeField> fields, JSONObject data) {
|
for (int i = 0, c = fields.size(); i < c; i++) {
|
SeField seField = fields.get(i);
|
switch (seField.getType()) {
|
case "int":
|
f.SetField(i, data.getInt(seField.getName()));
|
break;
|
case "long":
|
f.SetField(i, data.getLong(seField.getName()));
|
break;
|
case "double":
|
f.SetField(i, data.getDouble(seField.getName()));
|
break;
|
case "datetime":
|
long date = data.getLong(seField.getName());
|
Timestamp time = new Timestamp(date);
|
setTimestamp(f, i, time);
|
break;
|
default:
|
f.SetField(i, data.getStr(seField.getName()));
|
break;
|
}
|
}
|
}
|
|
private static void setTimestamp(Feature f, int i, Timestamp time) {
|
if (null == time) return;
|
|
LocalDateTime local = time.toLocalDateTime();
|
f.SetField(i, local.getYear(), local.getMonthValue(), local.getDayOfMonth(), local.getHour(), local.getMinute(), local.getSecond(), 8);
|
}
|
|
/**
|
* 创建Geometry对象
|
*/
|
private static Geometry createGeometry(SeLayer seLayer, JSONObject geom) {
|
String type = geom.getStr("type");
|
JSONArray cs = geom.getJSONArray("coordinates");
|
|
Geometry g = null;
|
switch (type) {
|
case "Point":
|
g = new Geometry(ogr.wkbPoint);
|
g.AddPoint_2D(cs.getDouble(0), cs.getDouble(1));
|
break;
|
case "MultiLineString":
|
g = new Geometry(ogr.wkbMultiLineString);
|
for (int i = 0, c = cs.size(); i < c; i++) {
|
Geometry line = new Geometry(ogr.wkbLineString);
|
JSONArray lineArr = cs.getJSONArray(i);
|
for (int j = 0, d = lineArr.size(); j < d; j++) {
|
JSONArray arr = lineArr.getJSONArray(j);
|
line.AddPoint_2D(arr.getDouble(0), arr.getDouble(1));
|
}
|
g.AddGeometry(line);
|
}
|
break;
|
case "MultiPolygon":
|
g = new Geometry(ogr.wkbMultiPolygon);
|
for (int i = 0, c = cs.size(); i < c; i++) {
|
Geometry poly = new Geometry(ogr.wkbPolygon);
|
JSONArray polyArr = cs.getJSONArray(i);
|
for (int j = 0, d = polyArr.size(); j < d; j++) {
|
Geometry ring = new Geometry(ogr.wkbLinearRing);
|
JSONArray ringArr = polyArr.getJSONArray(j);
|
for (int k = 0, e = ringArr.size(); k < e; k++) {
|
JSONArray arr = ringArr.getJSONArray(k);
|
ring.AddPoint_2D(arr.getDouble(0), arr.getDouble(1));
|
}
|
poly.AddGeometry(ring);
|
}
|
g.AddGeometry(poly);
|
}
|
break;
|
}
|
return g;
|
}
|
|
private static int getGeometryType(String type) {
|
switch (type) {
|
case "point":
|
return ogr.wkbPoint;
|
case "polyline":
|
return ogr.wkbMultiLineString;
|
case "polygon":
|
return ogr.wkbMultiPolygon;
|
default:
|
return ogr.wkbUnknown;
|
}
|
}
|
|
private static void createLayerFields(Layer layer, List<SeField> fields) {
|
for (int i = 0, c = fields.size(); i < c; i++) {
|
SeField f = fields.get(i);
|
FieldDefn fd = new FieldDefn(f.getName(), getFieldType(f));
|
|
layer.CreateField(fd, i);
|
}
|
}
|
|
private static Integer getFieldType(SeField f) {
|
switch (f.getType()) {
|
case "int":
|
return ogr.OFTInteger;
|
case "long":
|
return ogr.OFTInteger64;
|
case "double":
|
return ogr.OFTReal;
|
case "datetime":
|
return ogr.OFTDateTime;
|
default:
|
return ogr.OFTString;
|
}
|
}
|
}
|