浅谈Supermap iClient for JavaScript 弹窗类

地图作为信息的载体和呈现方式,是GIS的重要组成部分,它是一个浏览信息的窗口,在信息日益发达的今天 ,各种地图应用如雨后春笋一般出现在大众眼前,而不是像以往一样太过局限于专业的领域。而弹窗,是作为地图信息的补充说明和描述的重要呈现方式,也广泛应用于各种地图应用中。一个好的前端界面的设计要灵活地使用空间,也要生动地完成与用户的交互,而在地图应用中,弹窗使用得好,不但会让人感觉舒适也会方便和增加与用户的交互,提升用户体验。如何使用和如何更好地使用iClient for JavaScript的弹窗(Popup)类,便是本文要探讨的话题。

一、 基础

1. 分类

普通弹窗SuperMap.Popup):同时也是弹窗类的基类,不仅可以直接new出来,还能被子类继承其公开的属性和方法,JS API手册列举的属性和方法均可被其子类继承。其默认出现位置是,弹窗左上角在给定坐标点。

其默认效果如下↓:



固定锚点位置弹窗SuperMap.Popup.Anchored):固定锚点位置的的浮动弹窗,可以围绕指定位置四周自适应显示。即当弹窗定位点(lonlat)在当前地图可视范围边缘时,会自动调整弹窗哪个角停靠在定位点。

其默认效果如下↓:



带小尾巴的弹窗SuperMap.Popup.FramedCloud):具有指向和边框的浮动弹窗。它虽然没有边缘自适应位置的效果,但具有边缘时移动地图使弹窗显示完整的效果和阴影效果。

其默认效果如下↓:


2. 使用

弹窗类的使用很简单,new一个加到地图里就好了,这里以FramedCloud为例,上代码

 1 var map = new SuperMap.Map("map");                //引号内map为页面div元素ID
 2
 3 //初始化FramedCloud类
 4 var framedCloud = new SuperMap.Popup.FramedCloud(
 5     "chicken",                              //弹窗的唯一标识ID,即加载在地图上的弹窗div的ID
 6    new SuperMap.LonLat(11339634, 4588716), //当前地图上的坐标点,用于定位弹窗位置
 7    new SuperMap.Size(120,60),             //弹窗内容的大小,可以为null
 8    ‘<div style="margin:25px 10px; padding:0;"> 弹窗内容,相当于div元素的innerHTML
 9 </div>‘,
10    null,                                //锚点,即弹窗怎么定位到坐标点
11    true,                               //bool,是否显示关闭按钮
12    null,                              //Function,关闭弹窗触发该回调函数
13    false                             //是否显示阴影,默认为true
14 );
15 framedCloud.fixedRelativePosition=true;        // 是否固定相对位置,默认为false。
16 var layer = new SuperMap.Layer.CloudLayer();  //初始化超图云图层
17 map.addLayers([layer]);                      //添加超图云图层
18 map.setCenter(new SuperMap.LonLat(11339634, 4588716), 4); //设置显示的中心点及比例尺级别
19 map.addPopup(framedCloud);                 //将弹窗加载到map控件上,即放在地图上
 就这样?就这样。 

JS API类参考里有更多的属性和方法,可以自己去调整、设置。上面的代码只是初始化时就给放个弹窗,显然不符合我们的需要,但是已经足够说明它的用法了。弹窗基础的用法就是这么用,弹窗内容的部分,你可以自由发挥了,可以使用第三方插件,JQuery UI教程)、BootStrap等等,你可以自由定制弹窗的内容。

一般我们怎么用?最常见的就是点击地图上的图标,任何可以注册点击事件的地方来添加弹窗。下面举个例子:

点击点对象,显示弹窗: 
       这里使用SuperMap.Layer.Vector图层上的点对象(其他对象也一样),点对象怎么得到,怎么风格化处理就不多说了,我们来看看它需要什么参数: 
       首先,最重要的参数,定位点,它是SuperMap.LonLat类型的,所以我们得想办法得到所点击的点的坐标。SuperMap.Layer.Vector图层上要素的点击事件可以用SuperMap.Control.SelectFeature来注册,设置onSelect属性并且设置其repeat属性为true,或者使用callbacks属性(JS API类参考可以看到支持的事件)来实现点击事件:

1 var selectFeature = new SuperMap.Control.SelectFeature(VectorLayer,{onSelect:onFeatureSelect,repeat:true,selectStyle:style});
2 //onSelect:{Function},当要素被选中时调用该方法,要求用户定义具体方法,该方法接收当前选中要素作为参数。
3 //function onFeatureSelect(e){}; 

顺便说下,设置VectorLayer要素选中状态样式的方法有很多,上面就是其中之一。 

我们来看看点击(这里是重复触发的选中事件)事件触发后,传给回调函数的参数里有没有我们想要的坐标参数,用console.log(e)看看:



虽然没有直接的lonlat对象,但好在有geometry对象,它就是这个点对象的信息,可是类参考里,SuperMap.Geometry.Point点对象没有直接获取lonlat对象的方法和属性,一种方法是new一个SuperMap.LonLat对象,我这里使用另外一种Geometry对象通用的方法,先用geometry.getBounds()方法获取Geometry对象的Bounds,再使用SuperMap.Bounds对象的Bounds.getCenterLonLat()方法获取其中心坐标点lonlat对象:

1 var lonlat= e.geometry.getBounds().getCenterLonLat();

有了定位点,接下来要怎么做就不用我多说了吧?这里再补充一下锚点属性的使用,它是用来定位弹窗相对于定位点位置用的,一般使用SuperMap.Icon对象,它不会在弹窗任何位置添加一个图标,使用它是因为不需要再构造一个包含大小信息和偏移量信息的对象,使用它可以使你的弹窗停靠在点图标图片的上方而不至于让小尾巴与图标重叠,效果对比如下↓:





有了上面的例子,那么其他Geometry对象就都ok了,只要参数给对了就行。 
       另外,有的朋友不想使用客户端图层再弹窗,那怎么办呢?iServer 7C开始支持属性瓦片,同时客户端也有相关对接的类,即:SuperMap.Layer.UTFGrid。JS API有这两个图层使用的相关示例,这里稍稍提示下:

UTFGrid使用SuperMap.Control.UTFGrid控件注册事件,支持的事件类型有点击(click)、悬停(hover)和拖拽(move)。

再补充个,为处理海量数据而生的麻点图,使用SuperMap.Control.GOIs控件注册其事件。

3.其他

  • 视具体弹窗类型不同,其构造函数的参数数量有所不同,FramedCloud的构造函数已包含了别的类型弹窗的所有参数,所以其余弹窗类型不再赘述。
  • 了解一下它们的继承关系,子类继承父类的属性和方法。

二、 进阶

类参考里的方法和属性及其组合不能做到你想要做的效果?总之就是想做通过iClient for JavaScript做不到的弹窗效果?看这里就对了,之所以是进阶而不是高级,是因为我下面要说的其实很简单,也不需要去对JS API的源码进行修改、重写和扩展。好了我就不卖关子了,一句话就可以说清楚:

添加到地图上的弹窗是div。

好了,我说完了,下课。 
       就这样?就这样!早该想到的是不是?这句话说完其实就已经很好的总结了接下来的内容了,那么接下来就简单的介绍下,然后小伙伴们就可以愉快地玩耍、尽情地发挥想象力了。

1. 弹窗内边距、滚动条、边框、阴影、半透明等等效果和动画效果

看图↓:



想起什么了吗?弹窗这个div的ID就是我们new这个弹窗时第一个参数给的,而知道了整个弹窗的div及其嵌套关系后这第一个问题就算解决了是吧?虽然类参考里有部分比如边框、透明度样式设置的方法,但根据这个来设置显然更灵活。 
       另外,通过iClient JS主题包(theme文件夹)中的style.css文件,可以找到部分弹窗类样式的定义:

1 .smFramedCloudPopupContent {
2     padding: 5px;
3     overflow: auto;
4 }

不建议在原文件修改(实在要改记得备份),你需要的只是定义个CSS样式覆盖或追加到默认样式,为保证覆盖掉默认样式,可以在样式后面加 !important,比如:

1 .smFramedCloudPopupContent{
2    overflow:hidden !important;
3    padding:0 !important;
4 }

上面的效果就是弹窗内容(你写的那部分的外层div)不显示滚动条,内边距为0。

当然,你可以在style.css(在\theme\default下)文件中搜索Popup相关的样式来设置,但是通过浏览器查看元素更直观方便,之所以要去查看下默认样式的定义是为了避免自定义样式不生效,现在你知道了,加个!important 覆盖掉默认的就好了。 
到此,你可以使用各种UI、动画库(推荐animate.css)了,可以尽情发挥了。

2. 实现弹窗随鼠标移动或随地图上点移动的思路

map上加上弹窗后,如何实现移动弹窗?每次位置更改(onlat属性)先移除弹窗再添加可不可以呢?当然是可以的,如果你不需要和用户交互也不考虑弹窗多的情况下的性能的话。这是一种方法,但是不用考虑。

首先,收集必要信息:

1. 我们已经知道弹窗的ID(new 弹窗时自己给的,也可以在浏览器里查看),要用要改变它的位置,只需要设置它样式的left和top值,怎么获取呢? 
       2.看看popup对象除了是个div外,有没有在map对象里

先看看map控件下有什么属性和方法:


属性 描述
popups {Array(SuperMap.Popup)} 地图上的弹窗列表。

方法 描述
getViewPortPxFromLayerPx 根据图层像素点坐标获取视图窗口像素点坐标
getViewPortPxFromLonLat 根据指定地理位置,返回其相对于当前地图窗口左上角的像素位置
getPixelFromLonLat 获取地图上的像素坐标。依照当前baselayer,将指定的地理点位置坐标, 转换成其相对于地图窗口左上角点的像素坐标
getLonLatFromPixel 根据相对于地图窗口左上角的像素位置,返回其在地图上的地理位置。依据当前baselayer转换成 lon/lat (经度/纬度)形。
getLayerPxFromLonLat 根据传入的大地坐标获取图层坐标对象
getLayerPxFromViewPortPx 根据视图窗口像素点坐标获取图层像素点坐标
removeAllPopup 移除所有弹出窗口。
removePopup 移除指定的弹出窗口。


对于第一种思路要求,使用getLonLatFromPixelgetPixelFromLonLat方法就可以实现了,而且不需要计算地图容器在页面中的位置,不过这样改了后,弹窗对象的lonlat等属性不会变化,需要的话可以手动改下它的属性;另外,自带的阴影(多个div拼合而成)也不会跟着移动,也需要手动改,跟上面的方法一样,或者不使用自带的阴影,而使用用弹窗DIV的CSS阴影样式,这里用setInterval简单模拟了下:

 1 function mouseClickHandler(e){
 2                 closeInfoWin();
 3
 4                 var framedCloud= new SuperMap.Popup.FramedCloud(
 5                     "chicken",
 6                     e.object.lonlat,
 7                     null,
 8                     ‘这里相当于innerHTML部分‘,
 9                     new SuperMap.Icon(‘‘, new SuperMap.Size(21,25), new SuperMap.Pixel(-10, -20)),
10                     true,
11                     null,
12                     true
13                 );
14                 framedCloud.panMapIfOutOfView=true;
15                 infowin = framedCloud;
16                 map.addPopup(framedCloud);
17                 //在一定范围内随机更改弹窗位置
18                 setInterval(function(){
19                     var px=map.getPixelFromLonLat(new SuperMap.LonLat(e.object.lonlat.lon+Math.random()*100000,e.object.lonlat.lat+Math.random()*100000));
20                     document.getElementById("chicken" ).style.left=px.x+"px";
21                     document.getElementById("chicken" ).style.top=document.getElementById("chicken" ).style.height+px.y;
22                 },100);
23             }


对于第二种思路,当然就是获取到popup对象,改它的lonlat属性,但是你会发现改了之后,弹窗并没有移动,因为你只是改了对象的属性,div并不受影响,除非刷新地图或重绘div。但是,还是有办法的,用SuperMap.Popup.updateSize()方法就可以了:

1 setInterval(function(){
2                     var lonlat=new SuperMap.LonLat(e.object.lonlat.lon+Math.random()*100000,e.object.lonlat.lat+Math.random()*100000);
3                     map.popups[0].lonlat=lonlat;
4                     map.popups[0].updateSize();
5                 },1000);
6             }

二者可以结合使用,第一种思路更为灵活。浏览器里多按f12,这很重要。



关于弹窗类,进阶的内容就到这里了,高级的内容大家就自己探索吧。希望本文能给你一些启发、开阔一些思路。

时间: 2024-12-20 02:01:33

浅谈Supermap iClient for JavaScript 弹窗类的相关文章

SuperMap iClient for JavaScript 之关联查询

人们常说,计划赶不上变化.同样的,在项目中,使用的数据也是在不断变化的,尤其是属性信息的改变.就比如说,地图上的地物,它的空间信息在比较长的时间内,都不会发生变化,他的属性信息在初期不完整或者与后来的信息不符合,这时就可以使用SuperMap iClient for JavaScript 的关联查询.       那如何进行关联查询呢?不急,我们先在iClient for JavaScript中去找找与关联查询相关的类或接口.       首先,JavaScript客户端内,查询从分布的服务类别

SuperMap iClient for JavaScript image出图

SuperMap iClient for JavaScript 客户端基于openlayers 开发. 目前最高版本为811,9D产品后推荐客户使用leaflet.openlayers客户端开发. 问题说明: iClient for JavaScript(classic)在客户端做动态出图选择SuperMap.Layer.TiledDynamicRESTLayer,对接 SuperMap iServer 的 REST 地图服务的分块动态栅格图层.简单说就是加载iServer发布的地图服务在客户端

浅谈Kotlin(三):类

浅谈Kotlin(一):简介及Android Studio中配置 浅谈Kotlin(二):基本类型.基本语法.代码风格 前言: 已经学习了前两篇文章,对Kotlin有了一个基本的认识,往后的文章开始深入介绍Kotlin的实战使用. 本篇介绍Kotlin中类的使用. 一.表现形式 首先看一段Java中定义类的形式,定义三个属性,每一个属性对应一个get.set方法,有一个toString()方法 /* * @author xqx * @emil [email protected] * create

浅谈JS之text/javascript和application/javascript

问题描述: JS在IE8以下浏览器运行异常 代码: <script>标签是这样子写的: <script type="application/javascript"> //执行语句 </script> 这是书写的时候Dreamweaver自动补全的.但是在自己运行的例子中我的script标签写的是: <script type="text/javascript"> //执行语句 </script> 将项目中的标

JavaScript 弹窗类的实现

JS的打印输出是由 doucument.write();实现的 document.write( )内可以书写变量 ,文字 文字需要加"". JS有两种方式插入到html的页面中  1:<script> 编写JS代码 <script> 这个标签放在<head>和<body>两个标签内部都可以 放在<body>标签可能影响<body>标签内部的html 的内容,可是由于代码执行时自上而下的 如果把JS代码放在<h

浅谈JavaEE中的JDBC模板类的封装实现以及合理的建立项目包结构(一)

从今天开始我们一起来聊下有关,javaEE开发中的一些知识,JavaEE的开发用于企业级的开发,但是现在企业中一般也不会使用JDBC开发,大部分都是使用自己公司开发的一套的框架,但是这些框架的架构一般也是会模仿着有名JavaEE开源三大开发框架SSH(Struts2+Spring+Hibernate)或者现在也很流行的SSM开发框架(Spring+SpringMVC+MyBatis) 来进行深度定制以便于适合自己企业的实际开发需求.有的人曾说既然去公司又是重新学习一套框架,还有必要学习开源的三大

浅谈:Hibernate中HibernateUtil工具类

首先我们需要知道为什么咱们要创建Hibernate工具类 一些固定而且经常使用的步骤我们期望做成一个工具类,以后再需要重复步骤时咱们仅需要引用此工具类就可以,从而避免了一直创建重复代码.比如加载数据库的驱动等,这里Hibernate中我们每个主程序都需要加载hibernate.cfg.xml文件.创建SessionFactory对象.创建Session对象.关闭session.这些都是固定化的步骤,因此我们将它们写在工具类HibernateUtil中,以后咱们直接引用此文件创建各对象即可,大大减

浅谈href=#与href=javascript:void(0)的区别

#"包含了一个位置信息 默认的锚点是#top 也就是网页的上端 而javascript:void(0)  仅仅表示一个死链接 这就是为什么有的时候页面很长浏览链接明明是#可是跳动到了页首 而javascript:void(0) 则不是如此 所以调用脚本的时候最好用void(0) 或者<input onclick> <div onclick>等 打开新窗口链接的几种办法 1.window.open('url') 2.用自定义函数 <script>       

浅谈java中的对象、类、与方法的重载

对象: 一切皆为对象. 对象包括两部分内容:属性(名词形容词),行为(动词). 对象和对象之间是有关系的: 派生,关联,依赖. 类: 对同一类别的众多对象的一种抽象. 类,还是用来生成对象的一种模板,对象是类的一种具体化的表现. 面向对象的三大特性:封装,继承,多态. ? 1 2 3 4 class 类名{ 访问修饰符 成员变量的定义; 访问修饰符 成员函数(方法)的定义; } 访问修改符:默认不写,private,public. private,私有.只能被当前class 类名{}中的代码访问