WebGIS处理避免不了会用到wkt 字符串传入java后台转成Geometry的需求,但是我们以往的作法是后台直接接受一个字符串然后认为进行转换工作。其实Spring MVC 字符串自动映射成对象的处理方便相当方便,但是对于这种Geometry复杂类型是不支持的。其实要其支持也挺简单的,只要想法办让它知道如何进行转换即可。转换的思路有两种一种就是属性编辑器方式(PropertyEditor),另一种就是转换器方式(ConversionService)。这两种方式各有千秋:
1)定义属性编辑器GeometryEditor
package com.geoway.plan.core.support.propertyeditors;
import java.beans.PropertyEditorSupport;
import org.geotools.geometry.jts.JTSFactoryFinder;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryEditor extends PropertyEditorSupport {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Override
public void setAsText(String text) throws IllegalArgumentException {
WKTReader reader = new WKTReader(geometryFactory);
Geometry geom = null;
try {
geom = reader.read(text);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setValue(geom);
}
}
2)在需要用到Geometry转换的控制器加入如下代码
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Geometry.class, (PropertyEditor) new GeometryEditor());
}
这样就可以使实现转换了
1)定义GeometryConversionService转换服务
package com.geoway.plan.core.support.convert;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.GenericConversionService;
import com.vividsolutions.jts.geom.GeometryFactory;
public class GeometryConversionService implements ConversionService {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Autowired
private GenericConversionService conversionService;
private Set> converters;
@PostConstruct
public void afterPropertiesSet() {
if (converters != null) {
for (Object converter : converters) {
if (converter instanceof Converter, ?>) {
conversionService.addConverter((Converter, ?>)converter);
} else if (converter instanceof ConverterFactory, ?>) {
conversionService.addConverterFactory((ConverterFactory, ?>)converter);
} else if (converter instanceof GenericConverter) {
conversionService.addConverter((GenericConverter)converter);
}
}
}
}
@Override
public boolean canConvert(Class> sourceType, Class> targetType) {
return conversionService.canConvert(sourceType, targetType);
}
@Override
public boolean canConvert(TypeDescriptor sourceType,
TypeDescriptor targetType) {
return conversionService.canConvert(sourceType, targetType);
}
@Override
public T convert(Object source, Class targetType) {
return conversionService.convert(source, targetType);
}
@Override
public Object convert(Object source, TypeDescriptor sourceType,
TypeDescriptor targetType) {
return conversionService.convert(source, sourceType, targetType);
}
public Set> getConverters() {
return converters;
}
public void setConverters(Set> converters) {
this.converters = converters;
}
}
2)定义GeometryConverter转换器
package com.geoway.plan.core.support.convert;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryConverter implements Converter<String, Geometry> {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Override
public Geometry convert(String source) {
if (source == null || "".equals(source))
return null;
String wkt = source;
WKTReader reader = new WKTReader(geometryFactory);
Geometry geom = null;
try {
geom = reader.read(wkt);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return geom;
}
}
3)配置spring-mvc.xml文件
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="com.geoway.plan.core.support.convert.GeometryConversionService">
<property name="converters">
<set>
<bean class="com.geoway.plan.core.support.convert.GeometryConverter"/>
set>
property>
bean>
@RequestMapping(value = "/doConflictCheck.do", method = { RequestMethod.POST }, produces = { "application/json;charset=UTF-8" })
@ResponseBody
public BaseResponse doConflictCheck(HttpServletResponse httpResponse,
HttpServletRequest request,
@ModelAttribute PlanConflictcheckTask task) {
BaseObjectResponse response = new BaseObjectResponse();
try {
Object userId = PlanRequestUtil.getLoginUser(request);
task.setUserId(userId != null ? userId.toString() : null);
PlanConflictcheckTask taskResult = conflictcheckService
.saveConflictcheckTask(task);
response.setData(taskResult.getId());// 返回任务ID
} catch (Exception ex) {
ex.printStackTrace();
response.setMessage(ex.getMessage());
response.setStatus(CommonConstants.RESPONSE_STATUS_FAILURE);
logger.error(ex.getStackTrace());
}
return response;
}
@RequestMapping(value = "/postGeometry.do", method = { RequestMethod.POST }, produces = { "application/json;charset=UTF-8" })
@ResponseBody
public BaseResponse postGeometry(HttpServletResponse httpResponse,
HttpServletRequest request,
@RequestParam("geom") Geometry geom) {
……
这两种方法都适合doConflictCheck方法中的类型转换需求(PlanConflictcheckTask 中有个字段Geometry类型字段);但是postGeometry方法的对于控制器方式会报错。
前段传递的参数
doConflictCheck
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”area”
12
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”proId”
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”projectTYPE”
城市公共服务设施项目
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”landType”
绿地与广场用地
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”businessType”
能源
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”checkType”
1
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”geometry”
POLYGON((109.8640243053 24.586129461128,109.87846004989 24.47064350446,109.98638442606 24.450021012198,110.04069032235 24.509138823349,110.04687707003 24.58475462831,109.99188375733 24.615688366703,109.8640243053 24.586129461128))
——WebKitFormBoundaryNHeZScYVf03Da6Mv–
postGeometry
——WebKitFormBoundaryde1cujNHB5HFMjAa
Content-Disposition: form-data; name=”geom”
POLYGON((109.8640243053 24.586129461128,109.87846004989 24.47064350446,109.98638442606 24.450021012198,110.04069032235 24.509138823349,110.04687707003 24.58475462831,109.99188375733 24.615688366703,109.8640243053 24.586129461128))
——WebKitFormBoundaryde1cujNHB5HFMjAa–