需要引入的依赖
implementation group: 'org.geotools', name: 'gt-shapefile', version: '27.0'
需要注意的是gt-shapefile和commons-lang3好像有冲突,最好不要单独引入commons-lang3
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.smartcitysz.spatial.dataparse.dto.ShapeFileProperty;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.File;
import java.nio.charset.Charset;
import java.util.*;
public class ShapeFileUtils {
/**
* 读取坐标系信息
* @param filePath
* @return
*/
public static String readXY(String filePath){
File folder = new File(filePath);
if (!folder.isDirectory()) {
if (folder.toString().endsWith(".shp")) {
try {
return ShpFileUtils.readXY(filePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}else {
File[] files = folder.listFiles();
if (!(files.length > 0)) {
return null;
}
String xy = null;
for (File file : files) {
try {
if (file.getName().endsWith(".shp")) {
xy = ShpFileUtils.readXY(file.getAbsolutePath());
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
return xy;
}
return null;
}
/**
* 读取里面的属性信息,就是读取第一行数据
* @param filePath
* @return
*/
public static List<ShapeFileProperty> readProperties(String filePath) {
File folder = new File(filePath);
if (!folder.isDirectory()) {
if (folder.toString().endsWith(".shp")) {
try {
return getProperties(folder);
} catch (Exception e) {
e.printStackTrace();
}
} else {
}
}else{
File[] files = folder.listFiles();
if (!(files.length > 0)) {
return null;
}
for (File file : files) {
if (!file.getName().endsWith(".shp")) {
continue;
}
try {
return getProperties(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 读取里面的所有信息
* @param filePath
* @return
*/
public static JSONArray readValues(String filePath) {
JSONArray data = null;
String xy = null;
File folder = new File(filePath);
if (!folder.isDirectory()) {
if (folder.toString().endsWith(".shp")) {
try {
data = getValues(folder);
} catch (Exception e) {
e.printStackTrace();
}
}
}else{
File[] files = folder.listFiles();
if (!(files.length > 0)) {
return null;
}
for (File file : files) {
if (file.getName().toString().endsWith(".shp")) {
try {
data = getValues(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return data;
}
private static JSONArray getValues(File file) throws Exception{
JSONArray array = new JSONArray();
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(map);
//字符转码,防止中文乱码
((ShapefileDataStore) dataStore).setCharset(Charset.forName("utf8"));
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
FeatureIterator<SimpleFeature> features = collection.features();
try {
while (features.hasNext()) {
SimpleFeature feature = features.next();
Iterator<? extends Property> iterator = feature.getValue().iterator();
JSONObject object = new JSONObject();
while (iterator.hasNext()) {
Property property = iterator.next();
// System.out.println(property.getName() + ", " + property.getType().getBinding().getName() + ", " + property.getValue() + ", " + property.getDescriptor().getType().getBinding());
String name = property.getName().toString();
if (property.getType().getClass() == org.geotools.feature.type.AttributeTypeImpl.class){
if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("string")){
Object value = property.getValue();
if(value == null){
object.put(name, "");
}else {
object.put(name, value.toString());
}
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("date")){
Object value = property.getValue();
if(value == null){
object.put(name, null);
}else {
object.put(name, (Date) value);
}
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("double")){
Object value = property.getValue();
if(value == null){
object.put(name, null);
}else {
object.put(name, Double.parseDouble(value.toString()));
}
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("long")){
Object value = property.getValue();
if(value == null){
object.put(name, null);
}else {
object.put(name, Long.parseLong(value.toString()));
}
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("integer")){
Object value = property.getValue();
if(value == null){
object.put(name, null);
}else {
object.put(name, Integer.parseInt(value.toString()));
}
}else {
object.put(name, property.getValue());
}
}else {
object.put(name, property.getValue() + "");
}
}
if(object.keySet() != null && object.keySet().size() > 0){
array.add(object);
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
features.close();
dataStore.dispose();
}
// features.close();
// dataStore.dispose();
return array;
}
private static List<ShapeFileProperty> getProperties(File file) throws Exception{
List<ShapeFileProperty> list = new ArrayList<>();
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(map);
//字符转码,防止中文乱码
((ShapefileDataStore) dataStore).setCharset(Charset.forName("utf8"));
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
FeatureIterator<SimpleFeature> features = collection.features();
try {
boolean flag = true;
while (features.hasNext() && flag) {
SimpleFeature feature = features.next();
Iterator<? extends Property> iterator = feature.getValue().iterator();
while (iterator.hasNext()) {
Property property = iterator.next();
// System.out.println(property.getName() + ", " + property.getType().getBinding().getName() + ", " + property.getValue() + ", " + property.getDescriptor().getType().getBinding());
String name = property.getName().toString();
if (property.getType().getClass() == org.geotools.feature.type.AttributeTypeImpl.class){
if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("string")){
list.add(new ShapeFileProperty(name, "string"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("date")){
list.add(new ShapeFileProperty(name, "date"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("timestamp")){
list.add(new ShapeFileProperty(name, "timestamp"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("double")){
list.add(new ShapeFileProperty(name, "double"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("float")){
list.add(new ShapeFileProperty(name, "float"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("numeric")){
list.add(new ShapeFileProperty(name, "numeric"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("long")){
list.add(new ShapeFileProperty(name, "long"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("int")){
list.add(new ShapeFileProperty(name, "int"));
}else if(property.getDescriptor().getType().getBinding().toString().toLowerCase().contains("text")){
list.add(new ShapeFileProperty(name, "text"));
}else {
list.add(new ShapeFileProperty(name, "string"));
}
}else {
list.add(new ShapeFileProperty(name, "geo_shape"));
}
}
flag = false;
}
}catch (Exception e){
e.printStackTrace();
}finally {
features.close();
dataStore.dispose();
}
return list;
}
}
package com.smartcitysz.spatial.dataparse.util;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.type.AttributeDescriptorImpl;
import org.geotools.feature.type.GeometryDescriptorImpl;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class ShpFileUtils {
private static Logger LOG = LoggerFactory.getLogger(ShpFileUtils2.class);
public static String readXY(String shpFile) {
ShapefileDataStore shpDataStore = null;
try {
ShpFileInfoModel shpFileInfoModel = new ShpFileInfoModel();
CoordinateReferenceSystem coordinateSystem;
File file = new File(shpFile);
shpDataStore = new ShapefileDataStore(file.toURI().toURL());
shpDataStore.setCharset(StandardCharsets.UTF_8);
String typeName = shpDataStore.getTypeNames()[0];
shpFileInfoModel.setTypeName(typeName);
SimpleFeatureType schema = shpDataStore.getSchema(typeName);
coordinateSystem = schema.getCoordinateReferenceSystem();
String wkt = null;
if (coordinateSystem != null) {
wkt = coordinateSystem.toWKT();
if (StringUtils.isNotBlank(wkt)) {
wkt = wkt.replaceAll("\\r?\\n", " ");
}
}
shpDataStore.dispose();
return wkt;
} catch (IOException e) {
if (shpDataStore != null) shpDataStore.dispose();
LOG.error("ShapeFile文件解析元数据异常");
}
return null;
}
public static Integer readSrid(String shpFile) {
ShapefileDataStore shpDataStore = null;
try {
ShpFileInfoModel shpFileInfoModel = new ShpFileInfoModel();
CoordinateReferenceSystem coordinateSystem;
File file = new File(shpFile);
shpDataStore = new ShapefileDataStore(file.toURI().toURL());
shpDataStore.setCharset(StandardCharsets.UTF_8);
String typeName = shpDataStore.getTypeNames()[0];
shpFileInfoModel.setTypeName(typeName);
SimpleFeatureType schema = shpDataStore.getSchema(typeName);
coordinateSystem = schema.getCoordinateReferenceSystem();
String wkt = null;
if (coordinateSystem != null) {
Integer srid = CRS.lookupEpsgCode(coordinateSystem, true);
return srid;
}
shpDataStore.dispose();
return null;
} catch (Exception e) {
if (shpDataStore != null) shpDataStore.dispose();
LOG.error("ShapeFile文件解析元数据异常");
}
return null;
}
@Data
public static class ShpFileInfoModel {
/**
* schema
*/
private String typeName;
/**
* 坐标范围
*/
private Double[] extent = new Double[4];
/**
* 属性,不带有几何属性
*/
private List<AttributeDescriptorImpl> otherAttributes;
/**
* 几何属性
*/
private GeometryDescriptorImpl geometryAttribute;
/**
* 坐标系,也可从geometryAttributeDescriptor中获取
*/
private CoordinateReferenceSystem coordinateSystem;
}
@Data
public static class GeometryModel {
/**
* 几何类型
*/
private GeometryType type;
/**
* 坐标系
*/
private String wkt;
}
public enum GeometryType {
None("None"),
Point("Point"),
MultiPoint("MultiPoint"),
Polyline("Polyline"),
Polygon("Polygon"),
MultiPolygon("MultiPolygon"),
Multipatch("Multipatch");
private final String type;
public String getType() {
return type;
}
GeometryType(String type) {
this.type = type;
}
}
/**
* 通过wkt获取坐标系名称
*
* @param coordinateSystem
* @return [地理、投影、高程基准]
*/
public static String[] parseCoordinateReferenceSystemName(CoordinateReferenceSystem coordinateSystem) {
String[] name = new String[]{"", "", "", "", ""};
if (coordinateSystem != null) {
String wkt = coordinateSystem.toWKT();
return parseCoordinateReferenceSystemName(wkt);
}
return name;
}
/**
* 通过wkt获取坐标系名称
*
* @param wkt 坐标系定义文件
* @return [坐标系、地理、投影、中央经线、高程基准]
*/
public static String[] parseCoordinateReferenceSystemName(String wkt) {
String[] name = new String[]{"", "", "", "", ""};
if (StringUtils.isNotBlank(wkt)) {
if (wkt.contains("PROJCS[\"")) {
int i = wkt.indexOf("PROJCS[\"");
String wktNew = wkt.substring(i + 8);
int i1 = wktNew.indexOf("\"");
name[2] = wktNew.substring(0, i1);
}
if (wkt.contains("PARAMETER[\"central_meridian\",")) {
int i = wkt.indexOf("PARAMETER[\"central_meridian\",");
String wktNew = wkt.substring(i + 29);
int i1 = wktNew.indexOf("]");
name[3] = wktNew.substring(0, i1);
}
if (wkt.contains("GEOGCS[\"")) {
int i = wkt.indexOf("GEOGCS[\"");
String wktNew = wkt.substring(i + 8);
int i1 = wktNew.indexOf("\"");
name[1] = wktNew.substring(0, i1);
}
if (wkt.contains("VERTCS[\"")) {
int i = wkt.indexOf("VERTCS[\"");
String wktNew = wkt.substring(i + 8);
int i1 = wktNew.indexOf("\"");
name[4] = wktNew.substring(0, i1);
}
if (StringUtils.isNotBlank(name[2])) {
name[0] = name[2];
} else if (StringUtils.isNotBlank(name[1])) {
name[0] = name[1];
}
}
return name;
}
}