前文再续,书接上一回:java读取shapefile且用arcgis for js展示
java怎么读取shapefile呢?
shapefile是esri公司最先搞出来的,那么arcgis应该是有相关的类库的吧?好像找不到?我问过搞移动端的同事,arcgis for android确有处理shapefile的类库,处理起来易如反掌。但是,在WEB系统,服务器端从shapefile读出数据,最终是要在前端浏览器中展示,像我们目前在建的项目,就是要用arcgis for js来展示这些数据,而安卓系统类似CS项目,有很大的不同。最大的不同,WEB系统中,数据要以JSON的形式给前端,这样才好处理。arcgis for android,没接触过,心存敬畏,会不会很庞大?有没有用?不清楚,我有点害怕,本能地放弃了。
arcgis for java的SDK应该是arcgis engine吧。有时间要了解下。
在java世界里,处理空间信息,最流行的也许就是用GeoTools了,一个开源的JAVA处理空间信息类库。
网上例子很多,但大同小异。其实读出shp的数据一点都不难。难就难在,geotools读出来的数据形式,如果转成json的话,是GeoJson,而不是EsriJson,前端想用arcgis for js绘制,很难。所以,读取出来后,要转成EsriJson。如何转换,是另一个课题。现在,先读出来再说。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.dbf.DbaseFileHeader;
import org.geotools.data.shapefile.dbf.DbaseFileReader;
import org.geotools.data.shapefile.files.ShpFiles;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
/*
shapefile操作类
*/
public class ShapefileHelper {
public static Object read(String path) throws IOException {
/*
参数path就是shp文件的完整路径,如:E:\\蟠桃会资源清查\\调查图斑.shp
系统会自动检查同一个目录下有没有其他相关文件,有的话会一并读出,
相关文件的路径无须给出
.shp 存储地理形状和位置信息
.dbf 存储属性信息
.shx 索引文件
.prj 坐标系
.cpg 字符编码,如UTF-8
读取出来的结果类型为 List<Map<String, Object>>
*/
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
File file = getFile(path);
if (file == null) {
return list;
}
String charset = getCharSet(path);
FileDataStore store = FileDataStoreFinder.getDataStore(file);
((ShapefileDataStore)store).setCharset(Charset.forName(charset));
SimpleFeatureSource featureSource = store.getFeatureSource();
SimpleFeatureCollection collection = featureSource.getFeatures();
SimpleFeatureIterator features = collection.features();
while (features.hasNext()) {
Map<String, Object> item = new HashMap<String, Object>();
SimpleFeature f = features.next();
Collection<Property> p = f.getProperties();
Iterator<Property> it = p.iterator();
while (it.hasNext()) {
Property pro = it.next();
String field = pro.getName().toString();
field = field.equals("the_geom") ? "wkt" : field;
String value = pro.getValue().toString();
item.put(field, value);
}
list.add(item);
}
return list;
}
private static File getFile(String path){
File file = new File(path);
if (file == null) {
System.out.println("找不到路径:" + path);
}
return file;
}
/*
获取shapefile字符编码
如果存在.cpg文件,则从中读取,否则默认为UTF-8
*/
private static String getCharSet(String path){
String charset = "UTF-8";
int p = path.lastIndexOf(".");
String cpg = path.substring(0,p) + ".cpg";
File file = getFile(cpg);
if(file != null) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(cpg, "r");
charset = raf.readLine();
raf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return charset;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
pom.xml
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>23.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>23.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>23.0</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
测试一下
@Test
void readSha() throws IOException {
List<Map<String, Object>> list = (List<Map<String, Object>>) ShapefileHelper.read("E:\\蟠桃会资源清查\\导出成果20200420093045-2\\导出成果20200420093045\\图斑矢量\\调查图斑.shp");
Console.print(list.size());
}
- 1
- 2
- 3
- 4
- 5
但是,从shapefile里读出内容十分轻松,但这只是第一步,要想在前端的arcgis for js中展示出来,考验才刚刚开始。
请听下回分解。