kettle自定义拼接json格式输出,arcgis的json格式为例子

源文件下载 :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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值