由于GIS海量数据的特点,在进行开发分词查询、模糊查询等功能是,虽然用Oracle等数据库的分词技术也能实现,但总体效率不高,考虑ES在查询方面强大的效率,我开始了解ES与GIS结合实现高效率查询的方法。
1、搭建ES环境,我这里用到的ES6.2.4版本。
2、安装ES插件,包括IK、pinyin等;
3、Oracle SDE环境配置,我主要使用其中sde.st_astext(shape)方法,将Oracle中的空间数据转换成WKT格式;
4、应用Logstash6.2.4版本实现,将空间数据导入ES;
5、应用Java ESRest客户端,对ES进行查询,抛弃Oracle;
但是,在将Oracle中的空间数据导入ES的过程中,发现导入的WKT格式数据有极小的部分数据缺失POLYGON前缀。首先考虑的是可能数据问题,通过Geometry修复格式缺失问题依然存在。经网上查找,发现以下解决方案;
创建一个Oracle的Function:
create or replace function real_st_astext(geom1 in clob) return clob is
geometry clob;
tempGeom clob;
geom clob;
lonlatStr clob;--第一段经纬度字符串
firstStr clob;--第一个点的经纬度
lastIndex int;--第一个点最后一次出现的游标
begin
geom := trim(geom1);
geom := replace(geom,'( ','(');
geom := replace(geom,' (','(');
geom := replace(geom,') ',')');
geom := replace(geom,' )',')');
geom := replace(geom,', ',',');
geometry := upper(geom);
if geom like '(((%' then
geometry := 'MULTIPOLYGON' || geom;
else
if geom like '((%' then
tempGeom := substr(geom, instr(geom, '((') + 2, length(geom));
lonlatStr := substr(tempGeom, 0, instr(tempGeom, ')')-1);
firstStr := trim(substr(lonlatStr, 0, instr(lonlatStr, ',')-1));
lastIndex := instr(lonlatStr, firstStr, -1);
if lastIndex = length(lonlatStr) - length(firstStr) + 1 then
geometry := 'POLYGON '||geom;
else
geometry := 'MULTILINESTRING ' || geom;
end if;
else
if geom like '(%' then
if geom like '%,%' then
geometry := 'LINESTRING' || geom;
else
geometry := 'POINT' || geom;
end if;
end if;
end if;
end if;
return geometry;
end;
以如下方式查询即可:
select real_st_astext(sde.st_astext(Shape)) as WKT from XZQH;
系统实现效果如下:
1、拼音搜索
2、中文搜索
3、点击图标地块展示