暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

APEX开发实践(十一):APEX地图进阶开发(一)

1519

原文再续,书接上一回。本文讲述APEX地图组件的进阶开发。


一、geojson数据转换成Oracle数据库的GEOMETRY数据


首先为了能够实现更加复杂的查询和展现,我们要把上文中导入数据库的geojson转换成sdo_geometry数据类型并建立索引。


先在原来的表中增加一个sdo_geometry字段spatial_geo。存放“多边形”数据。(APEX的SQL工作室的对象浏览器里不能创建sdo_geometry类型的字段,所以只能用命令行的方式创建)。


alter table shanghai_geo add spatial_geo MDSYS.SDO_GEOMETRY


sdo_util.from_geojson()函数把geojson字段转换并更新到spatial_geo中。


update shanghai_geo aa set spatial_geo = (select sdo_util.from_geojson(GEOMETRY) from shanghai_geo bb where aa.id = bb.id)


由于在APEX地图里,大部分的数据查询和展现都是基于“点”类型。所以再创建一个“点”类型数据spatial_point_geo


alter table shanghai_geo add spatial_point_geo MDSYS.SDO_GEOMETRY


用Oracle数据库里通过多边形计算出中心点的spatial函数sdo_geom.sdo_centroid(),计算出中心点并更新到spatial_point_geo中。


update shanghai_geo set spatial_point_geo = sdo_geom.sdo_centroid( spatial_geo, 1 )


创建sdo_geometry元数据和索引。切记切记:不要用SQL工作室里的SQL命令创建元素据和索引(已知bug)。直接在SQL工作室的对象浏览器里点击右上角的“+”号,用引导方式创建空间索引。选中sdo_geometry字段后,剩下的就一路默认点下去就可以了。通过这种方式创建的索引,同时会更新表对应的geo元数据表user_sdo_geom_metadata


做完以上的geojson到Oracle数据库的GEOMETRY之后,我们可以把之前做的APEX地图改成以SDO_GEOMETRY的数据类型查询和展现。


二、交互报表和地图联动

实现目的,当点击交互报表的特定数据行的时候,地图上对应的区域居中并显示相关数据。


第一步,建一个交互报表。以及一个隐藏项P3_ID用来传递参数;


第二步,建一个页级的全局函数showFeature();


function showFeature( pId ) {

apex.item( "P3_ID").setValue( pId );

apex.event.trigger( $("#custom-map-region"), "refresh_and_center" );

}


这里:

custom-map-region是上一篇微文的第六节中设置的地图上海市行政区的静态ID

refresh_and_center是后面要设置的动态操作的事件名



第三步,在交互报表的属性里定义一个链接列。当点击的这个链接的时候,调用showFeature(),传入当前列的主键“ID”。


第四步,我们要做一个“点”图层,用来定位选中的区域。


第五步,创建一个自定义的动态操作centre after refresh。当点击交互报表的数据行链接的时候,通过javascript要实现三个动作:1,刷新地图;2,选中的区域归中;3,显示信息窗口。

首先要注意动态操作中的“When”的设置。

“Custom Event”和“jQuery Selector”里的设置一定要和第二步里javascript的定义对应上。


然后,要运行的javascript脚本如下:


var lMapRegion       = apex.region("custom-map-region"), //获取地图所在区域

lFeatureId       = apex.item("P3_ID").getValue(), //获取区域ID

//

lCenterLayerId   = lMapRegion.call("getLayerIdByName", "4search"), //获取需要展现中心点的图层的名称

lInfoLayerId     = lMapRegion.call("getLayerIdByName", "ShanghaiRegion"), //获取需要展现信息标签的图层的名称

//

lCenterFeature   = lMapRegion.call("getFeature", lCenterLayerId, lFeatureId ), //获取中心点信息

lInfoFeature     = lMapRegion.call("getFeature", lInfoLayerId, lFeatureId ), //获取标签信息

lCurrentZoom = lMapRegion.call("getMapCenterAndZoomLevel").zoom, //获取缩放值

//

lPosition;

if ( lCenterFeature.geometry ) {

lPosition    = lCenterFeature.geometry.coordinates;

lMapRegion.call( "closeAllInfoWindows" ); //刷新(关闭已有的信息标签)

lMapRegion.call( "setCenter", lPosition ); //中心点定位

lMapRegion.call( "setZoomLevel", 9 ); //设置缩放值

setTimeout( function() { //显示信息标签

lMapRegion.call(

"displayPopup",

"infoWindow",

lInfoLayerId,

lFeatureId.toString(),

false,

{lng: lPosition[0], lat:lPosition[1]}

) }, 200 );

}

完成后,效果如下图:


=====   End   =====


更多Oracle APEX的知识和技巧,请猛戳下面二维码持续关注微信公众号“APEX中文社区”和“徐大爷的学习笔记”。


APEX中文社区


徐大爷的学习笔记





文章转载自徐大爷的学习笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论