1 导入所需要lib pom.xml
…………
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>25.0</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.4</version>
</dependency>
2 编写工具类
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.FeatureWriter;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
/**
* @author deilsky
* @date 2021/4/25 12:32
* @description 导出SHP工具类
*/
public class ShapeFileUtils {
private ShapefileDataStore shapefileDataStore;
private Map<String, Serializable> param;
private SimpleFeatureTypeBuilder builder;
private FeatureWriter<SimpleFeatureType, SimpleFeature> writer;
private Polygon polygon;
private List<GisResult.Features> features;
private String dir;
private List<GisResult.Fields> fields;
private File target;
public interface ComplateListener {
void complate();
}
private ShapeFileUtils() {
}
public static ShapeFileUtils create() {
return new ShapeFileUtils();
}
public ShapeFileUtils addDir(String dir) {
this.dir = dir;
return this;
}
public ShapeFileUtils addFields(List<GisResult.Fields> fields) {
this.fields = fields;
return this;
}
public ShapeFileUtils addTargetFile(File target) {
this.target = target;
return this;
}
private synchronized void createParam(URL url) {
this.param = new HashMap<>(1);
this.param.put(ShapefileDataStoreFactory.URLP.key, url);
}
private synchronized void createSimpleFeatureTypeBuilder108(List<GisResult.Fields> fields) throws FactoryException, IOException {
this.builder = new SimpleFeatureTypeBuilder();
CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");
this.builder.setCRS(crs);
this.builder.setName("ShapeFile");
this.builder.add("the_geom", MultiPolygon.class);
String name;
for (GisResult.Fields field : fields) {
name = field.getName();
if (name.length() <= 10) {
this.builder.add(name.toUpperCase(), String.class);
}
}
this.shapefileDataStore = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(this.param);
this.shapefileDataStore.setCharset(Charset.forName("GBK"));
this.shapefileDataStore.setTimeZone(TimeZone.getDefault());
this.shapefileDataStore.createSchema(this.builder.buildFeatureType());
this.writer = shapefileDataStore.getFeatureWriter(shapefileDataStore.getTypeNames()[0], null);
}
private synchronized void createSimpleFeatureTypeBuilder102(List<GisResult.Fields> fields) throws FactoryException, IOException {
this.builder = new SimpleFeatureTypeBuilder();
String wkt = "GEOGCS[\"GCS_WGS_1984\", DATUM[\"D_WGS_1984\", SPHEROID[\"GCS_WGS_1984\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], AUTHORITY[\"EPSG\",\"6326\"]], PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], UNIT[\"degree\", 0.017453292519943295], AXIS[\"Geodetic latitude\", NORTH], AXIS[\"Geodetic longitude\", EAST], AUTHORITY[\"EPSG\",\"4326\"]]";
CoordinateReferenceSystem crs = CRS.parseWKT(wkt);
this.builder.setCRS(crs);
this.builder.setName("ShapeFile");
this.builder.add("the_geom", MultiPolygon.class);
String name;
for (GisResult.Fields field : fields) {
name = field.getName();
if (name.length() <= 10) {
this.builder.add(name.toUpperCase(), String.class);
}
}
this.shapefileDataStore = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(this.param);
this.shapefileDataStore.setCharset(Charset.forName("GBK"));
this.shapefileDataStore.setTimeZone(TimeZone.getDefault());
this.shapefileDataStore.createSchema(this.builder.buildFeatureType());
this.writer = shapefileDataStore.getFeatureWriter(shapefileDataStore.getTypeNames()[0], null);
}
private synchronized Polygon createPolygon(List<List<List<Double>>> rings) {
List<Coordinate> coordinates = new ArrayList<>();
for (List<List<Double>> ring : rings) {
for (List<Double> doubles : ring) {
coordinates.add(new Coordinate(doubles.get(0), doubles.get(1)));
}
}
polygon = new GeometryFactory().createPolygon(coordinates.toArray(new Coordinate[0]));
return polygon;
}
public ShapeFileUtils addFeatures(List<GisResult.Features> features) {
this.features = features;
return this;
}
/**
* 导出shp 对应 arcmap 10.8
*/
public synchronized void execute108(ComplateListener listener) throws IOException, FactoryException {
createParam(this.target.toURI().toURL());
createSimpleFeatureTypeBuilder108(this.fields);
GisResult.Features.Attributes attributes;
SimpleFeature simpleFeature;
GisResult.Features.Geometry geometry;
long startTime = System.currentTimeMillis();
System.out.println("start: " + startTime);
for (GisResult.Features feature : this.features) {
attributes = feature.getAttributes();
geometry = feature.getGeometry();
simpleFeature = this.writer.next();
simpleFeature.setAttribute("the_geom", createPolygon(geometry.getRings()));
Map<String, Object> map = new Gson().fromJson(attributes.toString(), new TypeToken<Map<String, Object>>() {
}.getType());
for (String s : map.keySet()) {
if (s.length() <= 10) {
simpleFeature.setAttribute(s.toUpperCase(), map.get(s) != null ? map.get(s) : "");
}
}
this.writer.write();
}
long endTime = System.currentTimeMillis();
System.out.println("end: " + endTime);
System.out.println("execution time: " + (endTime - startTime) / 60 + " second");
this.writer.close();
this.shapefileDataStore.dispose();
listener.complate();
}
/**
* 导出shp 对应 arcmap 10.2
*/
public synchronized void execute102(ComplateListener listener) throws IOException, FactoryException {
createParam(this.target.toURI().toURL());
createSimpleFeatureTypeBuilder102(this.fields);
GisResult.Features.Attributes attributes;
SimpleFeature simpleFeature;
GisResult.Features.Geometry geometry;
long startTime = System.currentTimeMillis();
System.out.println("start: " + startTime);
String val;
Charset charset = Charset.forName("GBK");
for (GisResult.Features feature : this.features) {
attributes = feature.getAttributes();
geometry = feature.getGeometry();
simpleFeature = this.writer.next();
simpleFeature.setAttribute("the_geom", createPolygon(geometry.getRings()));
Map<String, Object> map = new Gson().fromJson(attributes.toString(), new TypeToken<Map<String, Object>>() {
}.getType());
for (String s : map.keySet()) {
if (s.length() <= 10) {
val = map.get(s) != null ? String.valueOf(map.get(s)) : "";
simpleFeature.setAttribute(s.toUpperCase(), StringUtils.isEmpty(val) ? "" : new String(val.getBytes(charset), charset));
}
}
this.writer.write();
}
long endTime = System.currentTimeMillis();
System.out.println("end: " + endTime);
System.out.println("execution time: " + (endTime - startTime) / 60 + " second");
this.writer.close();
this.shapefileDataStore.dispose();
listener.complate();
}
}
import org.geotools.referencing.CRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import java.util.List;
/**
* @author deilsky
* @date 2021/4/19 12:07
* @description TODO
*/
public class GisResult {
private String objectIdFieldName;
private String globalIdFieldName;
private String geometryType;
private SpatialReference spatialReference;
private List<Fields> fields;
private List<Features> features;
public String getObjectIdFieldName() {
return objectIdFieldName;
}
public void setObjectIdFieldName(String objectIdFieldName) {
this.objectIdFieldName = objectIdFieldName;
}
public String getGlobalIdFieldName() {
return globalIdFieldName;
}
public void setGlobalIdFieldName(String globalIdFieldName) {
this.globalIdFieldName = globalIdFieldName;
}
public String getGeometryType() {
return geometryType;
}
public void setGeometryType(String geometryType) {
this.geometryType = geometryType;
}
public SpatialReference getSpatialReference() {
return spatialReference;
}
public void setSpatialReference(SpatialReference spatialReference) {
this.spatialReference = spatialReference;
}
public List<Fields> getFields() {
return fields;
}
public void setFields(List<Fields> fields) {
this.fields = fields;
}
public List<Features> getFeatures() {
return features;
}
public void setFeatures(List<Features> features) {
this.features = features;
}
public static class SpatialReference {
private int wkid;
private int latestWkid;
public int getWkid() {
return wkid;
}
public void setWkid(int wkid) {
this.wkid = wkid;
}
public int getLatestWkid() {
return latestWkid;
}
public void setLatestWkid(int latestWkid) {
this.latestWkid = latestWkid;
}
}
public static class Fields {
private String name;
private String alias;
private String type;
private int length;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
}
public static class Features {
private Geometry geometry;
private Attributes attributes;
public Geometry getGeometry() {
return geometry;
}
public void setGeometry(Geometry geometry) {
this.geometry = geometry;
}
public Attributes getAttributes() {
return attributes;
}
public void setAttributes(Attributes attributes) {
this.attributes = attributes;
}
public static class Geometry {
private List<List<List<Double>>> rings;
public List<List<List<Double>>> getRings() {
return rings;
}
public void setRings(List<List<List<Double>>> rings) {
this.rings = rings;
}
}
/**
* 此类为对应的 Feature 属性
**/
public static class Attributes {
@Override
public String toString() {
return "{" +
"objectid=" + objectid +
", ownername='" + ownername + '\'' +
", adregion='" + adregion + '\'' +
", parcelname='" + parcelname + '\'' +
", parcelid='" + parcelid + '\'' +
", users='" + users + '\'' +
", cropland=" + cropland +
", avgoutput=" + avgoutput +
", disasterinfo='" + disasterinfo + '\'' +
", lasttype='" + lasttype + '\'' +
", lastvarieties='" + lastvarieties + '\'' +
", lastyield=" + lastyield +
", lastdisasterinfo='" + lastdisasterinfo + '\'' +
", croptype='" + croptype + '\'' +
", cropvarieties='" + cropvarieties + '\'' +
", predictyield=" + predictyield +
", usertel='" + usertel + '\'' +
", parcelarea='" + parcelarea + '\'' +
'}';
}
private int objectid;
private String ownername;
private String adregion;
private String parcelname;
private String parcelid;
private String users;
private int cropland;
private int avgoutput;
private String disasterinfo;
private String lasttype;
private String lastvarieties;
private int lastyield;
private String lastdisasterinfo;
private String croptype;
private String cropvarieties;
private int predictyield;
private String usertel;
private String parcelarea;
public int getObjectid() {
return objectid;
}
public void setObjectid(int objectid) {
this.objectid = objectid;
}
public String getOwnername() {
return ownername;
}
public void setOwnername(String ownername) {
this.ownername = ownername;
}
public String getAdregion() {
return adregion;
}
public void setAdregion(String adregion) {
this.adregion = adregion;
}
public String getParcelname() {
return parcelname;
}
public void setParcelname(String parcelname) {
this.parcelname = parcelname;
}
public String getParcelid() {
return parcelid;
}
public void setParcelid(String parcelid) {
this.parcelid = parcelid;
}
public String getUsers() {
return users;
}
public void setUsers(String users) {
this.users = users;
}
public int getCropland() {
return cropland;
}
public void setCropland(int cropland) {
this.cropland = cropland;
}
public int getAvgoutput() {
return avgoutput;
}
public void setAvgoutput(int avgoutput) {
this.avgoutput = avgoutput;
}
public String getDisasterinfo() {
return disasterinfo;
}
public void setDisasterinfo(String disasterinfo) {
this.disasterinfo = disasterinfo;
}
public String getLasttype() {
return lasttype;
}
public void setLasttype(String lasttype) {
this.lasttype = lasttype;
}
public String getLastvarieties() {
return lastvarieties;
}
public void setLastvarieties(String lastvarieties) {
this.lastvarieties = lastvarieties;
}
public int getLastyield() {
return lastyield;
}
public void setLastyield(int lastyield) {
this.lastyield = lastyield;
}
public String getLastdisasterinfo() {
return lastdisasterinfo;
}
public void setLastdisasterinfo(String lastdisasterinfo) {
this.lastdisasterinfo = lastdisasterinfo;
}
public String getCroptype() {
return croptype;
}
public void setCroptype(String croptype) {
this.croptype = croptype;
}
public String getCropvarieties() {
return cropvarieties;
}
public void setCropvarieties(String cropvarieties) {
this.cropvarieties = cropvarieties;
}
public int getPredictyield() {
return predictyield;
}
public void setPredictyield(int predictyield) {
this.predictyield = predictyield;
}
public String getUsertel() {
return usertel;
}
public void setUsertel(String usertel) {
this.usertel = usertel;
}
public String getParcelarea() {
return parcelarea;
}
public void setParcelarea(String parcelarea) {
this.parcelarea = parcelarea;
}
}
}
}
3 编写对应Controller
@GetMapping("/educe/{ownername}")
public ModelAndView test(@PathVariable String ownername, HttpServletResponse response, HttpServletRequest request) {
String url = "http://xxx.xxx.xxx.xxx:xx/arcgis/rest/services/JZNparcel/FeatureServer/0/query?f=json&outFields=*&where=ownername";
try {
url += URLEncoder.encode("='" + ownername + "'", "utf8");
logger.info(url);
String ret = HttpUtils.create().get(url);
//HttpUtils 参考我的另一篇文章;
GisResult result = new Gson().fromJson(ret, new TypeToken<GisResult>() {
}.getType());
if (null != result) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String dayDir = sdf.format(new Date());
String realPath = request.getSession().getServletContext().getRealPath("/resources/educe/" + dayDir + "/" + ownername + "/");
File dir = new File(realPath);
if (dir.exists()) {
dir.delete();
}
dir.mkdirs();
File targetFile = new File(dir.getAbsolutePath(), ownername + ".shp");
if (targetFile.exists()) {
targetFile.delete();
}
targetFile.createNewFile();
ShapeFileUtils.create().addTargetFile(targetFile).addDir(dir.getAbsolutePath()).addFields(result.getFields()).addFeatures(result.getFeatures())
.execute102(() -> {
logger.info("ShapeFileUtils:complate");
File zip = new File(dir.getParent(), ownername + ".zip");
if (zip.exists()) {
download(request, response, zip);
} else {
try {
if (zip.createNewFile()) {
boolean zipResult = FileUtil.fileToZip(dir, zip);
if (zipResult) {
download(request, response, zip);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
} catch (FactoryException | IOException e) {
e.printStackTrace();
}
return null;
}