openlayers3 屏幕坐标的ol.interaction.modify移动后怎么获取点的坐标

1673人阅读
WebGIS(38)
用户请求地理数据或者其他数据,服务器要以一定的客户端能够识别的数据格式返回,数据格式是否高效,直接影响用户的体验!首先要求数据格式要是轻量级的,还要求客户端处理数据方便快捷,相较于XML,JSON满足这两个要求,且目前应用广泛,非常流行。而在传输地理信息方面,相应有GeoJSON。下面咱就来了解一下GeoJSON,并看看它怎么应用到应用里!
1. GeoJSON
可以说GeoJSON就是JSON格式,只不过是针对Geometry的JSON,遵循JSON的语法和格式,其解析方式和JSON完全相同。
GeoJSON是一种针对地理数据编码的数据传输格式,支持Point、LineString、Polygon、MultiPoint和MultiPolygon。多个地理要素用GeometryCollection表示,有多余的属性,使用Feature对象表示,一组Feature用FeatureCollection表示。以下代码就是一个Point类型的地理要素,包含name属性。
在你可以看到它的详细规范。
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [125.6, 10.1]
"properties": {
"name": "Dinagat Islands"
2. 如何利用它构建应用
上一篇我们初始化Vector图层时候,用到了GeoJSON文件:
vectorLayer = new ol.layer.Vector({
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
style: function(feature, resolution) {
style.getText().setText(resolution & 5000 ? feature.get('name') : '');
return [style];
其中的url:’data/geojson/countries.geojson’属性,便是一个GeoJSON文件,里边的内容是国家的边界信息:
这就相当于我们从服务器请求了GeoJSON数据,只不过不是通过查询数据库,而是请求文件。
我们抽取一部分分解一下,因为其它都是重复的:
{"type":"FeatureCollection","features":[
{"type":"Feature","id":"CHN","properties":{"name":"China"},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.339188,18.67 ...
第一个type属性,指定要素种类是要素集合;接下来的features属性是一个feature数组,每一个数组有type、id、properties、和geometry属性,其中properties是一个属性集合,这里只包含一个name属性,指国家的名字,可以包含多个属性,以都好分开即可;geometry也包含type和coordinates属性,type指定地理要素的种类,之前我们提到GeoJSON支持的种类,coordinates便是该要素的坐标。
2.2. 调取数据
当我们初始化vector图层,并将其加入map中,这些GeoJSON数据已经载入到Vector图层(当然,Vector支持GeoJSON格式)。我们可以添加处理事件,直接调取GeoJSON里包含的数据,咱们再回忆一下上一篇定义的鼠标点击事件:
* 鼠标点击的事件
map.on('click', function(evt) {
var pixel = map.getEventPixel(evt.originalEvent);
var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
var coordinate = evt.
var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(
coordinate, 'EPSG:3857', 'EPSG:4326'));
if(feature!==undefined){
content.innerHTML = '&p&你点击的坐标是:&/p&&code&' + hdms + '&/code&&p&这里属于:'+ feature.get('name') + '&/p&';
content.innerHTML = '&p&你点击的坐标是:&/p&&code&' + hdms + '&/code&&p&这里是大海!&/p&';
overlay.setPosition(coordinate);
map.addOverlay(overlay);
feature的定义中用到了forEachFeatureAtPixel这个函数,这个函数的上的解释如下:
* Detect features that intersect a pixel on the viewport, and execute a callback with each intersecting feature. Layers included in the detection can be configured through opt_layerFilter. Feature overlays will always be included in the detection.
函数原型如下:
ol.Map.prototype.forEachFeatureAtPixel =
function(pixel, callback, opt_this, opt_layerFilter, opt_this2){}
也就是说,这个函数会检测与pixel像素相交的要素feature,并对该feature调用callback函数。其它参数都是可选的,其中opt_layerFilter 可以配置检测的图层,可以保证的是,矢量要素一定在被检查之列。
这个函数执行之后,返回与像素相交的feature,然后我们可以调用相关的feature的属性等:
if(feature!==undefined){
content.innerHTML = '&你点击的坐标是:&&' + hdms + '&&这里属于:'+ feature.get('name') + '&';
content.innerHTML = '&你点击的坐标是:&&' + hdms + '&&这里是大海!&';
其中feature.get(‘name’)就是取用feature的name属性,这里是国家名‘China’!之所以添加feature是否为null,是因为大海处没有feature。
这样会有如下的效果:
OK,这样就将GeoJSON的要素定义、格式以及取用方法都讲清楚了,亲,你看明白了么,没有的话请留言告知哦!
其实从服务器请求一个GeoJSON文件(本文例子),和从服务器端查询数据库是一样一样的啊,就是利用AJAX或者其他通信技术,来发送请求,而服务器有相应的处理程序,直接将结果通过GeoJSON格式,返回就可以。下次我们说说用AJAX请求服务器端,然后返回GeoJSON的数据,及其解析方法。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:97458次
积分:1726
积分:1726
排名:第18129名
原创:58篇
评论:84条
阅读:15958
文章:25篇
阅读:693722512人阅读
OpenLayers(25)
WebGIS(38)
&&&&初始化一幅地图,必备的三要素之一就是视图(view),这个对象主要是控制地图与人的交互,如进行缩放,调节分辨率、地图的旋转等控制。也就是说每个 map对象包含一个 view对象部分,用于控制与用户的交互。
&&&&主要介绍 view 的作用和用法,并分析商用的地图应用中的相关的功能。功能的具体的实现与如何进行定制和优化,就超过了这篇文章的范围了。
&&&&view 类的定义可以在 GitHub 的 OpenLayers 项目中的
看到,我就不贴大篇幅的代码了,只是针对特定的点贴一下核心代码,需要看完整源码的到上面的链接去看。
一、 view 属性
&&&&view 的构造函数需要的参数是一个 olx.ViewOptions对象,这个对象的描述如下:
* Object literal with config options for the view.
* @typedef {{center: (ol.Coordinate|undefined),
constrainRotation: (boolean|number|undefined),
enableRotation: (boolean|undefined),
extent: (ol.Extent|undefined),
minResolution: (number|undefined),
maxResolution: (number|undefined),
minZoom: (number|undefined),
maxZoom: (number|undefined),
projection: ol.proj.ProjectionLike,
resolution: (number|undefined),
resolutions: (Array.&number&|undefined),
rotation: (number|undefined),
zoom: (number|undefined),
zoomFactor: (number|undefined)}}
比较重要的属性如下:
center 是一个坐标[x, y],表示地图视图的中心位置;
extent 是一个数组对象 – [left, bottom, right, top],表示地图视图的初始范围;
projection 是地图的投影坐标系统;
resolution 表示地图的分辨率,单位并不是普通的单位面积的像素,而是单位像素表示的距离单位,比如 米/像素;
rotation 表示地图的旋转角度;
zoom 表示地图初始的缩放级别。
&&&&这些属性的状态直接影响地图的外观和用户的交互,该对象用于初始化 view 的属性。 view 包含一个ol.ViewProperty数组:
ol.ViewProperty = {
CENTER: 'center',
RESOLUTION: 'resolution',
ROTATION: 'rotation'
&&&&除了初始化 ol.ViewProperty 中的属性,view 的属性还有 projection_属性,表示投影信息;一些限制属性maxResolution_ , minResolution_ , minZoom_ 等,主要是限制地图的最大和最小分辨率(比例尺)和最小缩放级别(zoom level)等。
&&&&定义view类的方法是 混合使用构造函数模式和原型模式,构造函数模式部分(如上面构造函数的定义),主要定义类的私有属性和私有函数,所以以上定义的为每个对象特有的属性,各个对象内容各异;原型模式主要定义类的公有方法,每个实例化的对象保存的都是原型的指针,所以原型模式定义的方法和属性只有一个实例,每个对象都引用这个实例。
&&&&下面我们就分别介绍其各个实例化的 view 对象的常用公有方法、作用和用法。
二、 view 方法
&&&&view 类的方法主要是针对 view 的属性的 get 和 set 方法,其基本的方法很多,我们将常用的方法进行归类:
rotate,ifDef
fitExtent,fitGeometry
getCenter,getProjection,getResolution,getRotation,getZoom
setCenter,setResolution,setRotation,setZoom
&&&&下面分别介绍这些方法的作用和用法,后面还有实例,让大家更清楚地了解这些方法执行的效果。
rotate(rotation , opt_anchor ),接受两个参数,旋转角度数(rotation)和旋转中心(opt_anchor,可选),将地图围绕 opt_anchor 旋转 rotation 角度;
isDef,检查地图的中心和分辨率是否已经设置,都设置返回 true,否则返回 false;
fitExtent(extent, size),接受两个参数:extent 和 size,extent 类型是 ol.Extent – [left, bottom, right, top],size由map.getSize()获取;该功能类似于 ArcGIS 的缩放到图层功能,将地图的view 缩放到 extent 区域可见的合适尺度;
fitGeometry(geometry, size, opt_options),参数是地理要素,地图尺寸和可选参数;根据给定的地理要素,将 view 缩放到适合地理要素显示的尺寸;
get ,getCenter() 获取地图的中心,返回一个地图中心的坐标;getResolution()获取地图的分辨率,即比例尺,返回一个表示比例尺的数值; getProjection()获取地图使用的”投影坐标系统”,如EPSG:4326;getRotation()获取地图的“旋转角度”;getZoom()获取地图的缩放级别,返回一个表示缩放级别的数值;以上的函数均不需要任何参数;
set ,setCenter(center),参数为ol.Coordinate类型 – [x, y],作用为设置地图的中心坐标;setResolution(number)设置地图的分辨率(比例尺);setRotation(number),参数为旋转的角度对应的值,并不是度数,如Math.PI,不是180度,作用是将地图旋转相应点角度,顺时针为正;setZoom(number)设置地图的缩放级别。
&&&&这些方法中,fit类方法和 set 类方法,调用都可以看到效果,其它的都是计算或者获取相应已经存在的值。下面我们通过实例来看看这些方法的效果。
三、 view 类应用实例
&&&&我们将 HTML 页面中加一个按钮,然后绑定一个点击事件,点击触发我们的功能。首先在 HTML 的最后面添加按钮:
&input id="setViewTrigger" type="button" value="Trigger"&&/input&
然后进行函数绑定:
var trigger = document.getElementById("setViewTrigger");
trigger.addEventListener("click", function(){
var view = map.getView();
地图初始情况如下图,每一个功能调用后,只贴一张效果效果图,就不贴原图了:
1、rotate(rotation, opt_anchor)
&&&&rotate 方法第一个参数是角度,为数值,单位不是度,180度对应数值PI,也就是3.1415926 · · ·;且正数表示顺时针旋转,如要想顺时针旋转60度,那么传入 Math.PI /3。
在单击事件中添加如下调用:
view.rotate(Math.PI / 3)
调用函数后效果图:
2、fitExtent(extent, size)
&&&&只要涉及到坐标运算的都要注意坐标转换,这幅地图的默认坐标系为 EPSG:3857,如果使用的 EPSG:4326要注意进行坐标转换,使用ol.proj.transformExtent(转换Extent)和ol.proj.transform(转换坐标)进行坐标转换。
在事件函数中添加如下这句:
view.fitExtent(ol.proj.transformExtent([76,18,140,56], 'EPSG:4326', 'EPSG:3857'), map.getSize());
其中 [76,18,140,56]是中国的外包矩形坐标,结果应该是适合显示中国全图的尺度。
函数调用后效果图:
3、fitGeometry(geometry, size, opt_options)
&&&&要缩放到要素级别,首先要先获得相应要素,这里我选择的是代表“尼泊尔”的版图;然后再传入参数,进行缩放。在事件函数中添加如下代码:
var feature = vectorLayer.getSource().getFeatures()[28]
var polygon = feature.getGeometry()
view.fitGeometry(polygon, map.getSize())
效果应该是将“尼泊尔”缩放到最合适可见的级别。调用后效果如图:
get 函数都不需要参数,只需要获得地图的 view 对象,在 view 对象上调用即可。
4.1 getZoom()
var zoom = view.getZoom();
alert(zoom);
初始状态的缩放值:
初始状态的缩放值为2,这与初始的设置相吻合:
我们接着将地图放大两次,然后再检查zoom值:
可见 zoom 值变成了4,可见zoom值就是地图的缩放级别。百度地图或者谷歌地图等旁边的侧条显示国家、省、市等级别的值就与这个相关。
4.2 getCenter()
函数执行结果是返回地图的中心坐标,类型为ol.Coordinate。添加如下代码:
var center = view.getCenter();
alert(center);
执行结果:
4.3 getProjection()
&&&&函数执行结果是返回一个ol.proj.Projection对象,代表地图的投影坐标系统,该对象有一个方法 getCode(),返回投影的 ESPG 代码。例如,添加如下代码:
var projection = view.getProjection().getCode()
alert(projection)
运行结果如下:
4.4 getResolution()
函数返回一个数值,代表地图当前的分辨率(比例尺),例如,添加如下代码:
var resolution = view.getResolution();
alert(resolution);
运行结果如下:
缩放到中国的版图,观察其分辨率的值是否改变:
4.5 getRotation()
&&&&函数返回一个数值,代表旋转的角度。正常情况下,为 0。我们尝试旋转 Math.PI/3,也就是60度,然后再调用函数获取,结果如下:
结果为1.5976,也就是 Math.PI /3。
5.1 setCenter(center)
&&&&接受一个参数:中心坐标,类型为 ol.Coordinate,无返回值。我们取尼泊尔境内的中心坐标:[82.666],然后将传入的坐标设置为地图的中心:
view.setCenter(ol.proj.transform([82.66363, 29.64666], 'EPSG:4326', 'EPSG:3857'));
&&&&首先我们将地图平移到大海的地方,然后执行这一句,地图就会平移到尼泊尔为中心。该函数并不会改变地图的缩放级别(zoom)和分辨率(resolution),只是将传入的坐标设置地图的中心。
设置新的中心后:
5.2 setResolution(resolution)
&&&&接受一个参数,一个代表分辨率(比例尺)的数值,无返回值,操作结果就是将地图的分辨率(比例尺)设置为传入的数值。和 setCenter 一样,这个函数并不负责其他的功能,它只会就地,将地图的分辨率设置为相应的值,地图中心并不会变。
view.setResolution(100)
&&&&分辨率(比例尺)表示真实的地物与图上的地物的大小比例,所以分辨率的值越大,那么表示地图会显示的越小,值越小,地图越大,越清楚。
&&&&默认的分辨率,为 01024,我们把分辨率设置为 100000,理论上应该地图会缩小。调用函数效果如下图:
5.3 setZoom(zoom)
&&&&接受一个数值参数,将地图的缩放级别设置为相应的数值代表的缩放级别,同样地图中心也不会受到影响。
&&&&缩放级别(zoom level)分为多级,值越小,那么表示地图会显示的越小,值越大,地图越大,越清楚,与分辨率的值正好相反的规则。
&&&&地图最初的缩放级别是 2,我们将其设置为 10,效果如下:
view.setZoom(10)
执行结果:
&&&&像百度地图中的左边有一个比例尺条,分为国家、省、市、县等几个缩放级别,也是利用该项功能。当检测到缩放级别的值变化时,将标尺的刻度移动到对应的位置,即可。
5.4 setRotation(rotation)
&&&&设置地图的旋转角度,接受参数为旋转的角度,执行结果就是将地图围绕当前的地图中心,旋转相应的角度。该函数和 rotate(rotation, opt_anchor) 方法极为类似,用法直接参照 rotate方法就可以。
view.setRotation(Math.PI / 2)
调用函数后,地图顺时针旋转了90度:
&&&&OK,到此为止,基本 view 所有的功能都介绍完了。总之,view主要控制地图与用户的最基本的交互,每个 map 对象必须包含一个 view 对象,也就是说每个 map 必须都支持缩放、平移等基本交互动作。
&&&&这样,联合上一篇的
,我将 建立一幅地图需要的三个要素: layers、view 和 target,已经讲了最重要的两个了,剩下一个 target,就是存放地图的 HTML 元素的 ID 值,没有讲的必要,就略过了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:97459次
积分:1726
积分:1726
排名:第18129名
原创:58篇
评论:84条
阅读:15958
文章:25篇
阅读:69372114网址导航关于Openlayer3的菜鸟认识-爱编程
关于Openlayer3的菜鸟认识
什么是OpenLayers?
OpenLayers 是一个专为Web GIS 客户端开发提供的JavaScript 类库包,用于实现标准格式发布的地图数据访问。从OpenLayers2.2版本以后,OpenLayers已经将所用到的Prototype.js组件 整合到了自身当中,并不断在Prototype.js的基础上完善面向对象的开发,Rico用到地方不多,只是在OpenLayers.Popup.AnchoredBubble类中圆角化DIV。
我眼里的Openlayer:
& &   说到openlayer不得不说其中的map,map是OpenLayers的核心组件,如果把开发openlayer3过程比做画画的话,那么map就是一个神奇的桌子,它是来承载各式各样的纸(layer),画画的背景想用地图做背景怎么办?这个时候ol.layer.Tile出来了,想加载网格中加载块状地图,非它莫属,想加载客户数据怎么办?ol.layer.Vector帮助你,好了背景图有了,自己画的也加上了,突然发现对背景跟自己画的有点不满意,想自己添加,修改怎么办,给map加上特效,ol.interaction.xxxx,想要画点你就加ol,interaction.Draw,想修改你就加上ol.interaction.Modify,当然在加特效之前你可以对地图做一些渲染,ol.FeatureOverlayer,因为默认的样式画出来的东西不一定会看的清。当然事实上远没有这没简单,每个类都有自己的方法。就说map吧,至少我用到最多的是它的on()跟once()方法,前者监听一种特定类型的事件,后者监听一次特定类型的事件,其中on()跟un()是配对使用的。其他的就不多说了,可以参考一下官方手册。
一些常用的例子
首先从Map的官方参考手册看起
The map is the core component of OpenLayers. For a map to render, a view, one or more layers, and a target container are needed.
从上面Map的定义看,我们可以知道map是OpenLayers的核心组件。对map进行渲染,我们至少需要一个view(视图),一个layers(层)和一个目标的容器。
根据定义我们创建一个
最简单的map。
&meta charset="utf-8"&
&title&GIS开发样例-V1.0&/title&
&meta content="Copyright (c) Leetao" name="copyright"&
&link rel="stylesheet" href="/jslib/openlayer-3.3.0/css/ol.css" type="text/css"&
&script src="/jslib/openlayer-3.3.0/build/ol-debug.js" type="text/javascript"&&/script&
&div id="map" class="map"&&/div&
var map = new ol.Map({
view: new ol.View({
center: [0, 0], //视图的初始中心
//用于缩放视图的初始分辨率
new ol.layer.Tile({
//Tile预渲染层
source: new ol.source.MapQuest({layer: 'osm'})
target: 'map'
结果如图:
简单地图创建结束,接着让我们在地图上画图案
简单的绘图
&meta charset="utf-8"&
&title&GIS开发样例-V1.0&/title&
&meta content="Copyright (c) Leetao" name="copyright"&
&link rel="stylesheet" href="/jslib/openlayer-3.3.0/css/ol.css" type="text/css"&
&script src="/jslib/openlayer-3.3.0/build/ol-debug.js" type="text/javascript"&&/script&
&div id="map" class="map"&&/div&
&form class="form-inline"&
&label&Geometry type &&/label&
&select id="type"&
&option value="None"&None&/option&
&option value="Point"&Point&/option&
&option value="LineString"&LineString&/option&
&option value="Polygon"&Polygon&/option&
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source
var map = new ol.Map({
view: new ol.View({
center: [0, 0],
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'osm'})
target: 'map'
//featureOverlay
var featureOverlay = new ol.FeatureOverlay({
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
stroke: new ol.style.Stroke({
color: '#ffcc33',
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
featureOverlay.setMap(map);
var typeSelect = document.getElementById('type');
function addInteraction() {
var value = typeSelect.
if (value !== 'None') {
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
source: source,
type: /** @type {ol.geom.GeometryType} */ (value)
map.addInteraction(draw);
typeSelect.onchange = function(e) {
map.removeInteraction(draw);
addInteraction();
addInteraction();
结果如下:
上面代码可以让你在Tile上绘点,线以及几何图形,当然如果你把(1)注释了,再尝试在上面绘点,你会发现绘制的图形变成透明的了,
如果你先把(2)注释给取消了,在把(1)给注释了,你会发现,这个时候绘图是可以看见的
绘图结束了就是该修改图了
简单的绘图以及修改图
只需要在原有基础上加个ol.interaction.Modify就可以修改了
代码如下:
&meta charset="utf-8"&
&title&GIS开发样例-V2.0&/title&
&meta content="Copyright (c) Leetao" name="copyright"&
&link rel="stylesheet" href="/jslib/openlayer-3.3.0/css/ol.css" type="text/css"&
&script src="/jslib/openlayer-3.3.0/build/ol-debug.js" type="text/javascript"&&/script&
&div id="map" class="map"&&/div&
&form class="form-inline"&
&label&Geometry type &&/label&
&select id="type"&
&option value="None"&None&/option&
&option value="Point"&Point&/option&
&option value="LineString"&LineString&/option&
&option value="Polygon"&Polygon&/option&
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source
var map = new ol.Map({
view: new ol.View({
center: [0, 0],
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'osm'})
target: 'map'
//featureOverlay
var featureOverlay = new ol.FeatureOverlay({
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
stroke: new ol.style.Stroke({
color: '#ffcc33',
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
featureOverlay.setMap(map);
var modify = new ol.interaction.Modify({
features: featureOverlay.getFeatures(),
deleteCondition: function(event) {
return ol.events.condition.shiftKeyOnly(event) &&
ol.events.condition.singleClick(event);
map.addInteraction(modify);
var typeSelect = document.getElementById('type');
var // global so we can remove it later
function addInteraction() {
var value = typeSelect.
if (value !== 'None') {
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
source: source,
type: /** @type {ol.geom.GeometryType} */ (value)
map.addInteraction(draw);
typeSelect.onchange = function(e) {
map.removeInteraction(draw);
addInteraction();
addInteraction();
当然可以添加特效也可以修改特效,采用map.removeInteraction(),可以在特定事件触发之后禁止修改亦或是禁止绘图
上面都是单层的,如果想加入客户数据,参照样例一,将注释(2)去掉即可。
现在我们尝试从后台加载数据,并对后台传来的数据进行二次修改
修改后台传来的数据
主要采用了ol.interaction.Select()方法
核心代码如下:
var raster = new ol.layer.Tile({
source: new ol.source.MapQuest({
layer: 'sat'
var vector = new ol.layer.Vector({
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
var select = new ol.interaction.Select();
var modify = new ol.interaction.Modify({
features: select.getFeatures()
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([select, modify]),
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
其中ol.interaction.Select是用来处理被选中的Vector的数据的。
最后附上官方手册部分翻译(博主自己翻译的,可能有错,只供参考)
如果文章存在错误,请指正。
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。

我要回帖

更多关于 openlayers3 显示坐标 的文章

 

随机推荐