开发工具与关键技术:SuperMap iClient JavaScript、VS2015、SuperMap iServer
作者:曾浩源
撰写时间:2019.01.16
对于SuperMap iClient JavaScript的周边查询,我的思路,如下:
第一,显示地图后先绘点,给点添加上自己喜欢的icon图标。
第二,绘圆,根据绘出的点,文本框内的半径大小,绘出圆形
第三,最后根据圆形查询出所需的数据,添上样式或者icon图标
接下来看一个例子:
根据某一个点,和自己需要的半径,查询出范围内的医院或杜康
脚本引用和简单的页面搭建,如下:
<link href="~/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="~/js/jquery.2.1.4.min.js"></script>
<script src="~/SuperMap/libs/SuperMap.Include.js"></script>@*使用超图的js*@
<style>
body {
margin: 0;
overflow: hidden;
background: #fff;
}
#map {
position: relative;
height: 510px;
border: 1px solid #3473b7;
}
</style>
<body onload="init()">
<div>
<input type="text" id="text" /><button type="button" onclick="selectpoint()">选择</button>
<input type="checkbox" id="hospital" value="医院" />医院
<input type="checkbox" id="dukang" value="杜康" />杜康
半径:<input type="text" id="radius" value="5000" />
<button type="button" onclick="query()">查询</button>
<button type="button" onclick="clearAll()">清除</button>
</div>
<div id="map">
</div>
</body>
接下来就是 js部分:
一、先是显示出地图
//最初先加载显示出地图
var AllLayer;
//声明url地图链接 切片地图用于显示 另一个用于获取数据
var url = "http://localhost:8090/iserver/services/map-ugcv5-BaiYunQupointbyMap/rest/maps/白云区_point@byMap";
var ShuJuurl = "http://localhost:8090/iserver/services/map-byMap/rest/maps/白云区_point@byMap";
function init() {
//第一步 创建新地图
map = new SuperMap.Map("map", {
controls: [
new SuperMap.Control.LayerSwitcher(),//图层管理器
new SuperMap.Control.ScaleLine(),//比例尺
new SuperMap.Control.PanZoomBar(),//平移缩放控件
new SuperMap.Control.Navigation({//鼠标事件(拖拽,双击、鼠标滚轮缩放)
dragPanOptions: {
enableKinetic: true//enableKinetic设置是否使用拖拽动画。默认为false,不使用动画
}
})]
})
//TiledDynamicRESTLayer用于对接地图服务的分块动态栅格图层
layerWorld = new SuperMap.Layer.TiledDynamicRESTLayer("白云区", url, { transparent: true, cacheEnabled: true }, { maxResolution: "auto" }); //获取图层服务地址
//transparent图层是否透明,默认为false
//cacheEnabled 是否使用服务端的缓存,默认为true
//maxResolution在图层实例化的时候设置图层最大的分辨率
layerWorld.events.on({ "layerInitialized": addLayer });//构造函数
}
//添加地图图层
function addLayer() {
//地图图层
map.addLayers([layerWorld]);//添加图层
map.setCenter(new SuperMap.LonLat(113.3, 23.27), 0);//设置中心点
}
二、绘点
绘点,就需要一个用于渲染矢量要素的图层和一个存放图标的标记图层
需要在方法init()里新建新的图层 和 添加 绘点的控件
先新建新的图层
//在方法init()里新建新的图层
//图层用于渲染矢量要素
AllLayer = new SuperMap.Layer.Vector("绘点图层");
//绘点 到这一步就可以绘点了 //绘点图层
drawPoint = new SuperMap.Control.DrawFeature(AllLayer, SuperMap.Handler.Point, { multi: true });
//标记图层 标记图层类 用于存放中心点的图层
markerlayer = new SuperMap.Layer.Markers("标记图层");
然后添加 绘点的控件
drawPoint
map.addControl(drawPoint); 的简写 如有其它的画线 画面等等 继续逗号隔开
如:drawPoint,drawPolygon,drawCircle
map = new SuperMap.Map("map", {
controls: [
new SuperMap.Control.LayerSwitcher(),//图层管理器
new SuperMap.Control.ScaleLine(),//比例尺
new SuperMap.Control.PanZoomBar(),//平移缩放控件
new SuperMap.Control.Navigation({//鼠标事件(拖拽,双击、鼠标滚轮缩放)
dragPanOptions: {
enableKinetic: true//enableKinetic设置是否使用拖拽动画。默认为false,不使用动画
}
}),
drawPoint//map.addControl(drawPoint); 的简写 如有其它的画线 画面等等 继续逗号隔开 如:drawPoint,drawPolygon,drawCircle
]
})
最后新建一个方法,是选择中心点按钮的点击事件,激活绘点
//点击绘点按钮 触发绘点
function selectpoint() {
drawPoint.activate();//激活、启动、开始
}
现在就可以肆无忌惮的绘点了
三、绘点结束后,触发事件,即为该点添加icon图标
需要在方法init()里写events.on事件
//绘点后触发的事件
drawPoint.events.on({ "featureadded": drawCompletedPoint });
既然有了新的事件,就为它新建事件啦
//绘点后 添加图标 和 获取选中点的xy坐标
function drawCompletedPoint(drawGeometryArgs) {
drawPoint.deactivate();//停止绘点
clearAll();//清除一次
var count = drawGeometryArgs.feature.geometry.components[0] //获取第一个点的数据
var x = count.x;//获取当前几何的界限上下左右除以2得到x轴,y同理
var y = count.y;
var size = new SuperMap.Size(30, 38);//设置图标大小
var offset = new SuperMap.Pixel(-(size.w / 2), -size.h);//用x,y坐标描绘屏幕坐标
var icon = new SuperMap.Icon('../SuperMap/images/maker_L_Blue.png', size, offset);//创建图标类
marker = new SuperMap.Marker(new SuperMap.LonLat(x, y), icon);
markerlayer.addMarker(marker);//为标记图层添加图标
$("#text").val(x + "," + y);//将获取的xy坐标给到文本框
}
//绘点正式结束
还有就是清除按钮
//清除按钮
function clearAll() {
AllLayer.removeAllFeatures();//删除矢量要素
markerlayer.clearMarkers();//清除中心点标记
}
绘点正式结束
四、绘点正式结束后,下一步操作是勾选复选框,点击查询。
也就是先需要获取被勾选的复选框的值,然后绘圆,根据圆形大小查询所勾选的内容
复选框有多个,所以需要一个数组存放,新建一个标记图层,新建渲染矢量要素图层(Vector),这里不新建渲染矢量要素图层,只新建标记图层
需要在方法init()里写新建标记图层
//新建用于存放周边查询的标记图层
markerlayer1 = new SuperMap.Layer.Markers("周边查询标记图层");
最后就是查询按钮的点击事件
//先声明一个数组 存放被勾选的值
var select = [];
function query() {//查询按钮
AllLayer.removeAllFeatures();//清除当前图层所有的矢量要素
select = [];//清空数组
markerlayer1.clearMarkers();//清空周边查询的标记
if ($("#hospital").prop("checked") == true) {//判断医院复选框是否被勾选
select.push($("#hospital").val());//是的话,将它的值(医院)存放进数组select
}
if ($("#dukang").prop("checked") == true) {//同上
select.push($("#dukang").val());
}
var r = $("#radius").val(), xy = $("#text").val();//获取半径,xy文本框
var array = xy.split(',');//根据,号切割字符串
var x = array[0], y = array[1];//分成x , y
var centerPoint = new SuperMap.Geometry.Point(x, y);//根据xy坐标获取中心点
r = parseInt(r) / 100000;//半径
//实例化多边形对象 创建 RegularPolygon 对象。 多边形的中心 半径。 边数 旋转角度
var circleP = SuperMap.Geometry.Polygon.createRegularPolygon(centerPoint, r, 360, 360);
var circleVector = new SuperMap.Feature.Vector(circleP);//图层用于渲染矢量要素
circleVector.style = {//图层样式
strokeColor: "#CAFF70",
fillColor: "#C6E2FF",
strokeWidth: 2,
fillOpacity: 0.5,
strokeOpacity: 0.5
};
AllLayer.addFeatures(circleVector);//加进显示出来图层
//到这里 圆形就可以显示出来啦
到这里就可以显示出圆形啦
但还需要查询:如下
//以下是 根据数据源和数据集,获取数据 声明三个变量
var queryParam_QU = [], queryByGeometryParams_QU, queryService_QU;
if (select.indexOf("杜康") > -1) {//判断select数组里面是否有杜康,没有的话返回-1
queryParam_QU.push(new SuperMap.REST.FilterParameter({
name: "P15医疗服务_point@byMap",
attributeFilter: "NAME like '%杜康%' or NAME like '%卫生站%' or NAME like '%社区%'"//我这里杜康包括杜康,卫生站,社区服务中心
}));
}
if (select.indexOf("医院") > -1) {//同上
queryParam_QU.push(new SuperMap.REST.FilterParameter({
name: "P15医疗服务_point@byMap",
attributeFilter: "NAME like '%医院%'"
}));//FilterParameter设置查询条件,name是必设的参数,(图层名称格式:数据集名称@数据源别名)
}
//Geometry 查询参数类 QueryByGeometryParameters
queryByGeometryParams_QU = new SuperMap.REST.QueryByGeometryParameters({
queryParams: queryParam_QU,
geometry: circleVector.geometry,
spatialQueryMode: SuperMap.REST.SpatialQueryMode.INTERSECT//该类定义了空间查询操作模式常量
});
//Geometry 查询服务类。QueryByGeometryService
queryService_QU = new SuperMap.REST.QueryByGeometryService(ShuJuurl, {
eventListeners: {
"processCompleted": processCompleted_QU,
"processFailed": processFailed_FW
}
});
queryService_QU.processAsync(queryByGeometryParams_QU); //processAsync负责将客户端的量算参数传递到服务端。
}
将客户端的量算参数传递到服务端后
“processCompleted”: processCompleted_QU,用这个方法可以接收,从而进行渲染矢量,为它添加图标,显示到地图
function processCompleted_QU(obj) {
var result = obj.result;
var feature, x, y, LocalMrker, index = 0;
if (result && result.recordsets) {
for (i = 0, recordsets = result.recordsets, len = recordsets.length; i < len; i++) {
if (recordsets[i].features) {
for (j = 0; j < recordsets[i].features.length; j++) {
feature = recordsets[i].features[j];
x = feature.geometry.x;//获取xy
y = feature.geometry.y;
names = feature.data.NAME;//获取到名字 判断名字
if (names.indexOf("杜康") != -1 || names.indexOf("卫生站") != -1 || names.indexOf("社区") != -1) {
index = 1;
size = new SuperMap.Size(18, 18);//图层大小
offset = new SuperMap.Pixel(-(size.w / 2), -size.h),//用x,y坐标描绘屏幕坐标
icon = new SuperMap.Icon("../SuperMap/images/maker_L_Blue.png", size, offset);//创建图标类
LocalMrker = new SuperMap.Marker(new SuperMap.LonLat(x, y), icon);//为标记图层添加图标
LocalMrker.id = index;
LocalMrker.name = feature.attributes.NAME;
LocalMrker.laction = feature.attributes.ADDRESS;
LocalMrker.TELEPHONE = feature.attributes.TELEPHONE;//为LocalMrker添加属性
}
if (names.indexOf("医院") != -1)//判断名字是否包含医院两字
{
index = 2;
size = new SuperMap.Size(15, 15);
offset = new SuperMap.Pixel(-(size.w / 2), -size.h),
icon = new SuperMap.Icon("../SuperMap/images/maker_L _Red2.png", size, offset);
LocalMrker = new SuperMap.Marker(new SuperMap.LonLat(x, y), icon);
LocalMrker.id = index;
LocalMrker.name = feature.attributes.NAME;
LocalMrker.laction = feature.attributes.ADDRESS;
LocalMrker.TELEPHONE = feature.attributes.TELEPHONE;//同上
}
LocalMrker.GISID = feature.attributes.SmID;//ID
LocalMrker.events.on({
"click": OpenZhanDianMessagepopupss1,//点击图标弹出弹窗方法
"touchstart": OpenZhanDianMessagepopupss1, //假如要在移动端的浏览器也实现点击弹框,则在注册touch类事件
"scope": LocalMrker
});
markerlayer1.addMarker(LocalMrker);//将标记添加进图层
}
}
}
}
}
//若不需要弹窗,到这一步 把LocalMrker.events.on的内容删除,即可
//查询方法出错,跳到该方法,弹出提示框
function processFailed_FW(e) {
alert(e.error.errorMsg);
}
若不需要弹窗,到这一步 把LocalMrker.events.on的内容删除,即可
以下是弹窗内容
//弹窗内容
var LayerPopul = null;//声明公共变量,方便写关闭弹窗关闭方法
function OpenZhanDianMessagepopupss1(obj) {
CloseLayerPointPopup();//关闭弹窗
var marker = this;//相当于marker = obj; 复制过来的
var index = marker.id;//index
var XCoordinate = marker.getLonLat().lon;//X轴
var YCoordinate = marker.getLonLat().lat;//Y轴
var GISID = marker.GISID;//ID
var laction = marker.laction;//地址
var name = marker.name;//名字
var TELEPHONE = obj.TELEPHONE;//电话
if (TELEPHONE == undefined) {
TELEPHONE = "";
}
var size = new SuperMap.Size(18, 18),//图标大小
offset = new SuperMap.Pixel(-18, -18);//用x,y坐标描绘屏幕坐标
var TatleText = "";
if (index == 2) {//index=2为医院 弹窗头标题为医院
TatleText = "医院";
}
else if (index == 1) {//同上
TatleText = "杜康";
}
var icon = new SuperMap.Icon("/SuperMap/images/marker-RK.png", size, offset);//创建图标类
var contentHTML =//弹窗内容
"<div style='font-size:14px;overflow-y:hidden;overflow:auto;color:#000;height:auto;width: 100%;max-height: 240px;padding-left: 5px;'>" +
"<b>" + TatleText + "名称: </b>" + name + "<br/>" +
"<b>" + TatleText + "地址: </b>" + laction + "<br/>" +
"<b>" + TatleText + "电话: </b>" + TELEPHONE + "<br/>" +
"<div style='text-align:center'><button class='layui-btn layui-btn-normal layui-btn-xs' onclick='EverySelect(" + XCoordinate + "," + YCoordinate + ")'> 周边查询</button><br/>" +
"</div></div>"; //设置在气泡中显示的内容
var popup = new SuperMap.Popup.FramedCloud(//具有指向和边框的浮动弹窗
"TuCengPopwin",//id,名字, 弹窗的唯一标识ID
new SuperMap.LonLat(XCoordinate, YCoordinate),//地图上弹窗显示的位置
null,//弹窗内容的大小。
contentHTML,//弹窗内容HTML的字符串表达
icon,//锚点。包含一个大小信息 SuperMap.Size 和偏移信息 SuperMap.Size 的对象。(一般为 SuperMap.Icon 类型)。
true,//是否显示关闭按钮。
function () {//关闭弹窗触发该回调函数。
CloseLayerPointPopup();
},
true//是否显示阴影,默认为true。如果显示阴影,那么popup位置就会固定
);
popup.autoSize = true;//根据弹窗内容自动调整弹窗大小
popup.panMapIfOutOfView = true;//是否移动地图以确保弹窗显示在窗口内
LayerPopul = popup;//为公共变量赋值
map.addPopup(popup);//将弹窗添加进地图
}
关闭弹窗
//关闭弹窗方法
function CloseLayerPointPopup() {
if (LayerPopul) {
try {
LayerPopul.hide();
LayerPopul.destroy();
}
catch (e) { }
}
}
因为每次点击查询时,都需要去除或清空上次的存放复选框选择值的数组,矢量要素,中心点标记,设置中心点的文本框,周边查询标记,和复选框的勾选状态
所以,清空按钮的方法要如下
//清除按钮
function clearAll() {
AllLayer.removeAllFeatures();//删除矢量要素
markerlayer.clearMarkers();//清除中心点标记
select = [];//清空复选框选择值
$("#text").val("");//设置中心点文本框为空
markerlayer1.clearMarkers();//清除周边查询标记
$("#hospital").prop("checked", false);
$("#dukang").prop("checked", false);
}
到最后,如果显示了弹窗,就会发现里面有个周边查询的按钮,该按钮的点击事件如下
//弹窗中,周边查询按钮
function EverySelect(x, y) {
clearAll();//调用清除按钮
var size = new SuperMap.Size(30, 38);//图标大小
var offset = new SuperMap.Pixel(-(size.w / 2), -size.h);//用x,y坐标描绘屏幕坐标
var icon = new SuperMap.Icon('../SuperMap/images/maker_L_Blue.png', size, offset);//创建图标类
marker = new SuperMap.Marker(new SuperMap.LonLat(x, y), icon);//为标记图层添加图标
markerlayer.addMarker(marker);//将图标添加进中心点标记图层
$("#text").val(x + "," + y);//为中心点文本框添加xy坐标
query();
}