源文件下载 :output-json.ktr
先上图,速度的话我跑了20万数据,16个字段,14000条/秒,机器是自己笔记本i5处理器,kettle给了4g内存
1.源数据如下,field01字段可能有特殊字符,需要把字段field05的经度和纬度截取出来
2.目标数据是arcgis的json格式数据,最后的拼接结果是一行数据并没有格式化,这里为了方便看
{
"displayFieldName": "",
"fieldAliases": {
"FID": "FID",
"field01": "field01",
"field02": "field02",
"field03": "field03",
"field04": "field04"
},
"geometryType": "esriGeometryPolygon",
"spatialReference": {
"wkid": 4490,
"latestWkid": 4490
},
"fields": [{
"name": "FID",
"type": "esriFieldTypeOID",
"alias": "FID"
}, {
"name": "field01",
"type": "esriFieldTypeString",
"alias": "field01",
"length": "200"
}, {
"name": "field02",
"type": "esriFieldTypeString",
"alias": "field02",
"length": "200"
}, {
"name": "field03",
"type": "esriFieldTypeString",
"alias": "field03",
"length": "200"
}, {
"name": "field04",
"type": "esriFieldTypeString",
"alias": "field04",
"length": "200"
}],
"features": [{
"attributes": {
"field01": "value1-1",
"field02": "value2-1",
"field03": "value3-1",
"field04": "value4-1"
},
"geometry": {
"rings": [
[
[200.11111, 10.44444],
[200.11112, 10.44445],
[200.11113, 10.44446],
[200.11111, 10.44444]
]
]
}
}, {
"attributes": {
"field01": "value1-2",
"field02": "value2-2",
"field03": "value3-2",
"field04": "value4-2"
},
"geometry": {
"rings": [
[
[100.11111, 20.44444],
[100.11112, 20.44445],
[100.11113, 20.44446],
[100.11111, 20.44444]
]
]
}
}]
}
3.主要思路
使用java脚本拼接头部数据,再把经纬度取出来拼接上去,取最后一行以用txt文本输出组件以json文件格式输出
4.java代码
import java.math.BigDecimal;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
if (first) {
initParms(); //初始化变量
first=false;
}
String field05 = get(Fields.In, "field05").getString(r);
String field06 = get(Fields.In, "field06").getString(r);
boolean isLastRow = get(Fields.In, "result").getBoolean(r);
String lastStr = getArcgisJsonStr(r,( field05 == null || "".equals(field06))?field06:field05,isLastRow);
//logBasic("attributes:" + lastStr);
Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());
get(Fields.Out, "lastStr").setValue(outputRow, lastStr);
putRow(data.outputRowMeta, outputRow);
return true;
}
StringBuilder oneStr3;
//初始化变量
public void initParms(){
oneStr3=new StringBuilder();
}
//最后一行数据的时候返回拼接的json字符串
public String getArcgisJsonStr(Object [] r , String str,boolean isLastRow){
//拼接数据
getOneStr3(r,str,isLastRow);
//返回最后拼接结果
if(isLastRow){
return "{\"displayFieldName\": \"\",\"fieldAliases\": {" + getOneStr1() + "},\"geometryType\" : \"esriGeometryPolygon\",\"spatialReference\" : {\"wkid\" : 4490,\"latestWkid\" : 4490},\"fields\": [" + getOneStr2() + "],\"features\": [" + oneStr3 + "]}";
}
return "";
}
//拼接json头部字段项
public String getOneStr1(){
String[] fields=getInputRowMeta().getFieldNames();
//头部需要加fid字段
String oneStr1="\"FID\" : \"FID\",";
//便利所有字段
for(int i=0;i<fields.length-3;i++){
if(i == fields.length-4){
oneStr1+="\""+fields[i]+"\" : \""+fields[i]+"\"";
}else{
oneStr1+="\""+fields[i]+"\" : \""+fields[i]+"\",";
}
}
return oneStr1;
}
//拼接json头部字段属性
public String getOneStr2(){
String[] fields=getInputRowMeta().getFieldNames();
//writeToLog("m","oneStr2:" + oneStr2);
//头部需要加fid字段
String oneStr2="";
oneStr2+="{\"name\" : \"FID\",";
oneStr2+="\"type\" : \"esriFieldTypeOID\",";
oneStr2+="\"alias\" : \"FID\"}";
oneStr2+=",";
//便利所有字段,这里要是数据格式要求严格,可以判断数据类型再拼接
for(int i=0;i<fields.length-3;i++){
if(i == fields.length-4){
oneStr2+="{\"name\" : \""+fields[i]+"\",";
oneStr2+="\"type\" : \"esriFieldTypeString\",";
oneStr2+="\"alias\" : \""+fields[i]+"\",";
oneStr2+="\"length\" : \"200\"}";
}else{
oneStr2+="{\"name\" : \""+fields[i]+"\",";
oneStr2+="\"type\" : \"esriFieldTypeString\",";
oneStr2+="\"alias\" : \""+fields[i]+"\",";
oneStr2+="\"length\" : \"200\"}";
oneStr2+=",";
}
}
return oneStr2;
}
//拼接数据,注意最后一行没有逗号
public void getOneStr3(Object [] r , String str,boolean isLastRow){
if(isLastRow){
oneStr3.append( "{\"attributes\" : {" + getAttributes(r) + "}," + "\"geometry\" : {\"rings\" : [[" + getLonLat(str) + "]]}}");
}else{
oneStr3.append( "{\"attributes\" : {" + getAttributes(r) + "}," + "\"geometry\" : {\"rings\" : [[" + getLonLat(str) + "]]}},");
}
}
//字段属性和字段值拼接
public String getAttributes(Object [] row){
String[] fields=getInputRowMeta().getFieldNames();
String formatStr="";
//便利所有字段
for(int i=0;i<fields.length-3;i++){
if(i == fields.length-4){
formatStr+="\""+fields[i]+"\" : \""+row[i]+"\"";
}else{
formatStr+="\""+fields[i]+"\" : \""+row[i]+"\",";
}
}
return formatStr;
}
//经纬度拼接
public String getLonLat(String jsArrObj) {
//System.out.println(jsArrObj.length());
int startIndex=0;
int endIndex=0;
String formatStr="";
String longitude="";
String latitude="";
Double minLon =100000.0;
Double maxLon = -100000.0;
Double minLat = 100000.0;
Double maxLat = -100000.0;
BigDecimal DIFFERENCE = new BigDecimal(0.5);
if( jsArrObj == null || "".equals(jsArrObj)) {
return formatStr;
}
for(int i=0;i<jsArrObj.length();i++) {
if(jsArrObj.charAt(i) == ':') {
startIndex= i + 1;
//System.out.println("point x or y start:" + i);
}
if(jsArrObj.charAt(i) == ',' && jsArrObj.charAt(i+1) == '"') {
endIndex=i;
longitude=jsArrObj.substring(startIndex, endIndex);
//System.out.println( "point x end:" + i);
//System.out.println("point x:" + jsArrObj.substring(startIndex, endIndex));
//---------------------------------------------
//先判断任意两个经度,纬度差值的绝对值不大于0.5
minLon = new BigDecimal(minLon).min(new BigDecimal(longitude)).doubleValue();//取最小值
maxLon = new BigDecimal(maxLon).max(new BigDecimal(longitude)).doubleValue();//取最小值
//判断差值是否小于0.5
if(new BigDecimal(maxLon).subtract(new BigDecimal(minLon)).compareTo(DIFFERENCE) == 1){
//差值大于0.5 该面数据舍弃,直接放回字符串0
return "";
}
}
if(jsArrObj.charAt(i) == '}') {
endIndex=i;
latitude=jsArrObj.substring(startIndex, endIndex);
minLat = new BigDecimal(minLat).min(new BigDecimal(latitude)).doubleValue();//取最小值
maxLat = new BigDecimal(maxLat).max(new BigDecimal(latitude)).doubleValue();//取最小值
//判断差值是否小于0.5
if(new BigDecimal(maxLat).subtract(new BigDecimal(minLat)).compareTo(DIFFERENCE) == 1){
//差值大于0.5 该面数据舍弃,直接放回字符串0
return "";
}
formatStr+="["+longitude+","+latitude+"],";
//最后一个字符
if(jsArrObj.charAt(i+1) == ']') {
//System.out.println(formatStr.substring(0, formatStr.indexOf(']') + 1));
formatStr+=formatStr.substring(0, formatStr.indexOf(']') + 1);
}
//System.out.println("point y end:" + i);
//System.out.println("point y:" + jsArrObj.substring(startIndex, endIndex));
}
}
//System.out.println("minLon:" + minLon + "\nmaxLon:" + maxLon + "\nminLat:" + minLat + "\nmaxLat:" + maxLat);
return formatStr;
}