geotools编写shp转sql,实现shp数据入Oracle Spatial库

概述

用到Oracle Spatial就很难避免shp文件的入库问题,虽然有shp2sdo工具,但是用起来不是很习惯,所以,本文讲述如何结合geotools实现shp2sql的转换。

效果

实现代码

package com.lzugis.geotools;

import com.lzugis.CommonMethod;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.filter.text.cql2.CQL;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import scala.util.parsing.combinator.testing.Str;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.lzugis.geotools.model.Fields;

public class Shp2Orcale {
    private final Map<String, String> fMap = new HashMap<>();

    private SimpleFeatureSource featureSource = null;
    private String tableName = "";
    private List<Fields> fields = new ArrayList<>();
    private CommonMethod cm = new CommonMethod();

    public Shp2Orcale(){
        fMap.put("string", "varchar2(64)");
        fMap.put("long", "long");
        fMap.put("double", "number");
        fMap.put("shape", "\"MDSYS\".\"SDO_GEOMETRY\"");
    }

    public void readShape(String shpfile){
        try {
            File file = new File(shpfile);
            ShapefileDataStore shpDataStore = null;

            shpDataStore = new ShapefileDataStore(file.toURL());
            //设置编码
            Charset charset = Charset.forName("GBK");
            shpDataStore.setCharset(charset);
            tableName = shpDataStore.getTypeNames()[0];
            featureSource =  shpDataStore.getFeatureSource (tableName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void getShpFields(){
        SimpleFeatureType schema = featureSource.getSchema();
        List<AttributeDescriptor> attrs= schema.getAttributeDescriptors();
        for(int i=0;i<attrs.size();i++){
            AttributeDescriptor attr = attrs.get(i);
            Class<?> cls = attr.getType().getBinding();
            String clsName = cls.getName();
            clsName = clsName.substring(clsName.lastIndexOf(".")+1).toLowerCase();
            Fields field = new Fields(attr.getLocalName(), clsName);
            fields.add(field);
        }
    }

    public void createTableSql(String sqlpath){
        cm.append2File(sqlpath, "--1.drop table\r\nDROP TABLE "+tableName+";");
        cm.append2File(sqlpath, "\r\n--2.create table\r\n");
        StringBuffer sql = new StringBuffer();
        sql.append("CREATE TABLE "+tableName+" (");
        for(int i=0, size = fields.size();i<size;i++){
            Fields field = fields.get(i);
            String filedname = field.getFieldmame().toLowerCase();
            filedname = filedname.equals("the_geom")?"shape":filedname;
            String fieldtype = field.getFieldtype();
            fieldtype = filedname.equals("shape")?"shape":fieldtype;
            sql.append(filedname+" "+fMap.get(fieldtype));
            if(i!=size-1) sql.append(", ");
        }
        sql.append(");");
        cm.append2File(sqlpath, sql.toString());
    }

    public void insertValueSql(String sqlpath) {
        try {
            cm.append2File(sqlpath, "\r\n--3.insert data");

            SimpleFeatureCollection result = featureSource.getFeatures();
            SimpleFeatureIterator itertor = result.features();

            StringBuffer sql = new StringBuffer();
            while (itertor.hasNext()){
                SimpleFeature feature = itertor.next();
                StringBuffer _sql = new StringBuffer();
                _sql.append("insert into "+tableName+" values(");
                for(int i=0, size = fields.size();i<size;i++){
                    Fields field = fields.get(i);
                    String filedname = field.getFieldmame();
                    filedname = filedname=="the_geom"?"shape":filedname;
                    String fieldtype = field.getFieldtype();

                    if(filedname!="shape"){
                        if(fieldtype.equals("string")){
                            _sql.append("'"+feature.getAttribute(filedname)+"'");
                        }else {
                            _sql.append(feature.getAttribute(filedname));
                        }
                    }else{
                        Geometry geom = (Geometry)feature.getAttribute("the_geom");
                        _sql.append("sdo_geometry('"+geom.toString()+"', 4326)");
                    }
                    if(i!=size-1) _sql.append(", ");
                }
                _sql.append(");\r\n");
                sql.append(_sql);
            }
            cm.append2File(sqlpath, sql.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 工具类测试方法
     * @param args
     */
    public static void main(String[] args) {
        Shp2Orcale shp2orcl =new Shp2Orcale();
        String shppath = "D:\\data\\wgs84\\capital.shp";
        String sqlpath = "D:\\data\\wgs84\\sql\\capital.sql";
        try{
            long start = System.currentTimeMillis();
            //读取shp文件
            shp2orcl.readShape(shppath);
            shp2orcl.getShpFields();
            shp2orcl.createTableSql(sqlpath);
            shp2orcl.insertValueSql(sqlpath);
            System.out.println("共耗时"+(System.currentTimeMillis() - start)+"ms");
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

说明: 1、对于比较复杂的线或面会出现sql太长的问题,文章里面加了一行简化的代码;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏古时的风筝

模拟实现Spring中的注解装配

在Spring中,XML文件中的bean配置是实现Spring IOC的核心配置文件,在早版本的Spring中,只能基于XML配置文件,配置各个对象之间的依赖关...

23350
来自专栏LhWorld哥陪你聊算法

Hadoop源码篇---解读Mapprer源码outPut输出

上次讲完MapReduce的输入后,这次开始讲MapReduce的输出。注意MapReduce的原语很重要:

14730
来自专栏技术栈大杂烩

Python: 函数与方法的区别 以及 Bound Method 和 Unbound Method

随着我们越来越频繁使用Python, 我们难免会接触到类, 接触到类属性和方法.但是很多新手包括我, 不知道方法 和 函数 的区别,这次简单来讨论下, 如果有哪...

34610
来自专栏对角另一面

lodash源码分析之baseFindIndex中的运算符优先级

本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

20980
来自专栏Ldpe2G的个人博客

Graphviz4S ---- 在Scala中使用DOT语言绘图的开源工具

之前需要在Scala中用到类似python的graphviz库的功能,用来在Mxnet中可视化网络结构,

17740
来自专栏恰童鞋骚年

剑指Offer面试题:27.最小的k个数

  这道题是典型的TopK问题,其最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),但...

16120
来自专栏王小雷

Python之数据聚合与分组运算

Python之数据聚合与分组运算 1. 关系型数据库方便对数据进行连接、过滤、转换和聚合。 2. Hadley Wickham创建了用于表示分组运算术语“spl...

26490
来自专栏撸码那些事

【图解数据结构】 栈&队列

19450
来自专栏性能与架构

Mysql order by排序优化

1. 加大max_length_for_sort_data参数的设置 在MySQL中,排序算法分为两种,一是只加载排序字段到内存,排序完成后再到表中取其他字段,...

37150
来自专栏码匠的流水账

聊聊storm trident spout的_maxTransactionActive

本文主要研究一下storm trident spout的_maxTransactionActive

11000

扫码关注云+社区

领取腾讯云代金券