在Java中操作空间文件需要得到Arcgis Engine的支持,通常也叫做AO环境,如何创建简单的AO环境可参考该文章:https://blog.csdn.net/qq_33285292/article/details/116201778。这边就不再展开细说ArcEngine For Java的开发环境了,话不多说这边直接看主业务方法,创建shp文件的方法。
createShpfile方法:
/****
* @Description // 生成shp文件 只导出图形不含字段信息
* @Date 16:55 2021/4/13
* @Param [
* shapeFolder, shp的真实目录
* shapeName, shp文件名称
* feature_array [{ "geometry":{},"attributes":{}}]
* ]
* @return boolean
**/
@Override
public boolean createShpfile(String shapeFolder,String shapeName,JSONArray feature_array) throws Exception{
IFeatureWorkspace pWS = null;
IWorkspaceEdit workspaceEdit = null;
try {
//ao环境需要 arcgis desktop 的支持
AoInitialize aoInit = null;
AoInitUtil aoInitUtil = new AoInitUtil();
aoInit = aoInitUtil.initializeEngine(aoInit);
File dir = new File(shapeFolder);
if (!dir.exists()) dir.mkdirs();
// 打开工作空间
IWorkspaceFactory pWSF = new ShapefileWorkspaceFactory();
IWorkspaceFactoryLockControl ipWsFactoryLock = new IWorkspaceFactoryLockControlProxy(pWSF);//解锁文件对象
pWS = (IFeatureWorkspace) pWSF.openFromFile(shapeFolder, 0);
// 设置字段集
IFields pFields = new Fields();
IFieldsEdit pFieldsEdit = (IFieldsEdit) pFields;
// 设置字段
IField pField = new Field();
IFieldEdit pFieldEdit = (IFieldEdit) pField;
// 创建类型为几何类型的字段
String strShapeFieldName = "shape";
pFieldEdit.setName(strShapeFieldName);
pFieldEdit.setType(esriFieldType.esriFieldTypeGeometry);
// 为esriFieldTypeGeometry类型的字段创建几何定义,包括类型和空间参照
// 创建空间参考
IGeometryDef pGeoDef = new GeometryDef();
IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit) pGeoDef;
pGeoDefEdit.setGeometryType(esriGeometryType.esriGeometryPolygon);
pGeoDefEdit.setSpatialReferenceByRef(new UnknownCoordinateSystem());
pFieldEdit.setGeometryDefByRef(pGeoDef);
pFieldsEdit.addField(pField);
this.setAttributeField(pFieldsEdit,"FD1","测试字段1",50,esriFieldType.esriFieldTypeString);
this.setAttributeField(pFieldsEdit,"FD2","测试字段2",null,esriFieldType.esriFieldTypeDouble);
//创建shapefile
IFeatureClass featureClass = pWS.createFeatureClass(shapeName, pFields, null, null,esriFeatureType.esriFTSimple, strShapeFieldName, "");
//开始编辑,shape中插入数据
workspaceEdit = (IWorkspaceEdit)pWS;
workspaceEdit.startEditing(false);
workspaceEdit.startEditOperation();
if(feature_array!=null && feature_array.size() > 0){ //遍历要素点信息
for(int i=0;i<feature_array.size();i++){
Map resultObj = (Map) feature_array.get(i);
IFeatureBuffer featureBuffer = featureClass.createFeatureBuffer();
IFeatureCursor featureCursor = featureClass.IFeatureClass_insert(true); //这个地方有个问题会产生wr.lock 锁文件
// 保存shape空间范围
String strgeometry = resultObj.get("geometry")==null?"":resultObj.get("geometry").toString(); //找到图形
IGeometry analyzeGeometry = AddShpUtils.jsonToGeometry(strgeometry);
featureBuffer.setShapeByRef(analyzeGeometry);
String strattributes = resultObj.get("attributes")==null?"":resultObj.get("attributes").toString(); //找到图形
JSONObject attr = JSONObject.fromObject(strattributes);
featureBuffer.setValue(featureClass.findField("FD1"), attr.get("FD1")!=null?attr.getString("FD1"):"");
featureBuffer.setValue(featureClass.findField("FD2"), attr.get("FD2")!=null?attr.getDouble("FD2"):"");
featureCursor.insertFeature(featureBuffer);
featureCursor.flush();
}
}
if (aoInit != null)
{
aoInit.shutdown();
aoInit = null;
}
if (ipWsFactoryLock.isSchemaLockingEnabled())//判断文件是否有锁,如果有就解除锁
{
ipWsFactoryLock.disableSchemaLocking();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}finally{
try {
if(workspaceEdit!=null){
workspaceEdit.stopEditOperation();
workspaceEdit.stopEditing(true);
}
} catch (IOException e1) {
e1.printStackTrace();
return false;
}
}
}
/***
* @Description //设置属性字段
* @Date 15:57 2021/5/10
* @Param [
* pFieldsEdit, IFieldEdit编辑字段对象
* fieldName, 字段名字
* AliasName, 字段说明
* fieldLength, 字段长度
* fieldType 字段类型
* ]
* @return void
**/
private void setAttributeField(IFieldsEdit pFieldsEdit,String fieldName,String AliasName,Integer fieldLength,int fieldType)throws Exception{
IField field3 = new Field();
IFieldEdit fieldEdit3 = (IFieldEdit) field3;
fieldEdit3.setName(fieldName);
fieldEdit3.setAliasName(AliasName);
if(fieldLength!=null) fieldEdit3.setLength(fieldLength);
fieldEdit3.setType(fieldType);
pFieldsEdit.addField(field3);
}
该方式适用于查询图层数据后将geometry和attributes 用于导出shp文件。但是我目前碰到一个至今都还没解决的问题,那就是在操作shp的时候 会产生lock锁文件,一共有三种锁 rd.lock,sr.lock,wr.lock。
在操作打开IFeatureCursor 的时候 利用 featureClass.IFeatureClass_insert(true) 利用游标打开featureClass的时候会产生wr.lock 这个锁文件目前都没办法彻底释放掉,唯一的办法就是重启容器才行,如果有大佬解决了咋们方便交流下,嘻嘻嘻。