Geometry类型自定义类型转换器

WebGIS处理避免不了会用到wkt 字符串传入java后台转成Geometry的需求,但是我们以往的作法是后台直接接受一个字符串然后认为进行转换工作。其实Spring MVC 字符串自动映射成对象的处理方便相当方便,但是对于这种Geometry复杂类型是不支持的。其实要其支持也挺简单的,只要想法办让它知道如何进行转换即可。转换的思路有两种一种就是属性编辑器方式(PropertyEditor),另一种就是转换器方式(ConversionService)。这两种方式各有千秋:

PropertyEditor方式,是控制器级别的。ConversionService是全局性的。

一、使用注解式控制器注册PropertyEditor(针对具体的controller类处理)

1、使用WebDataBinder进行控制器级别的注册PropertyEditor(控制器独享)

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());  
    }

这样就可以使实现转换了

二、通过ConversionService、Converter实现类型转换(系统全局转换器)

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> T convert(Object source, Class<T> 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文件

<!-- ①注册自定义ConversionService -->
    <mvc:annotation-driven conversion-service="conversionService" />
    <!-- 未注册时,请注册 genericConversionService-->
    <!--  <bean id="genericConversionService" class="org.springframework.core.convert.support.GenericConversionService"/>-->
    <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>

三、controller中部分代码

@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–

Cesium中的自定义材质可以通过使用ShaderMaterial实现。这需要您了解一些WebGL着色编程知识。 以下是一个简单的例子,演示如何创建一个自定义材质: ```javascript // 创建一个基本的ShaderMaterial var material = new Cesium.ShaderMaterial({ // GLSL顶点着色代码 vertexShaderSource: ` attribute vec3 position; attribute vec3 normal; attribute vec2 st; uniform mat4 modelViewProjectionMatrix; uniform mat3 normalMatrix; varying vec3 v_normal; varying vec2 v_st; void main() { gl_Position = modelViewProjectionMatrix * vec4(position, 1.0); v_normal = normalize(normalMatrix * normal); v_st = st; } `, // GLSL片元着色代码 fragmentShaderSource: ` varying vec3 v_normal; varying vec2 v_st; void main() { gl_FragColor = vec4(v_normal, 1.0); } `, }); // 将材质应用于一个Primitive var primitive = new Cesium.Primitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.BoxGeometry({ vertexFormat: Cesium.VertexFormat.POSITION_NORMAL_ST, minimum: new Cesium.Cartesian3(-1, -1, -1), maximum: new Cesium.Cartesian3(1, 1, 1), }), modelMatrix: Cesium.Matrix4.IDENTITY, }), appearance: material, }); ``` 在这个例子中,顶点着色将传递的顶点位置、法线和纹理坐标转换为标准的变量。片元着色使用法线作为颜色输出。您可以通过修改着色代码以及添加Uniform变量来实现更复杂的效果。 需要注意的是,由于自定义材质使用了WebGL着色编程,因此需要进行性能测试和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值