当前位置: 首页 > article >正文

将数据与OpenLayers结合在一起

无论您是向客户展示如何前往您的企业,显示水质采样点或对度假图片进行地理标记,地图都是一种呈现数据的有趣方式。 在网站上使用地图变得越来越普遍,人们经常使用免费服务,例如Google Maps,Microsoft Virtual Earth和Yahoo!。 地图。 这些主要参与者提供的工具非常有用,可以使您快速获取带有地图的网页。 但是,除了添加标记或航路点之类的基本功能之外,它们不是非常可定制的。

假设您是制图师或地理信息系统(GIS)的专业人士,代表一个人工作,或者是高级业余爱好者,并且希望从各种来源中获取多个数据集。 传统方法是使用Web映射解决方案,例如商业ESRI ArcIMS或开源MapServer工具。 两种工具都擅长允许您合并不同的数据源并显示它们。 但是,它们不允许您自己使用数据源,例如Google Maps和Virtual Earth。 此外,使用MapServer模板或自行编写JavaScript在网站上使用功能齐全的地图可能会很费时间,以实现良好的功能水平。

OpenLayers解决了这些问题。 使用OpenLayers,您可以轻松快捷地在您的网站上整理功能齐全的地图。 生成的地图可以使用来自各种来源的数据,包括公共服务器,MapServer,ArcIMS服务,ESRI ArcGIS甚至是NASA World Wind。 通过让地图使用MapServer驱动的Web地图服务(WMS)服务,您还可以包含自己的数据集,例如shapefile和栅格数据。

注意:如果你不熟悉的GIS术语,例如投影和shape文件,请参阅相关信息的链接,developerWorks文章“Linux上的应用程序中使用地理空间数据使用GDAL。”

图书馆架构概述

OpenLayers是一个独立JavaScript库,不需要服务器端组件或特定的Web服务器要求,它由一组组织良好JavaScript类组成。 起始位置是OpenLayers.Map ,实际的地图对象本身。 实例化各个图层类,例如Layer.ArcIMSLayer.Google ,并将其添加到地图中。 表示地图控件的类(例如Control.Pan )用于与地图进行交互。 最后,还有各种用于样式,数据格式,坐标存储等的实用程序类。 请参阅链接的OpenLayers API文档相关信息的完整文档。

本文在构建图1所示的示例网站时探索了这些类,该网站结合了Google Earth,Virtual Earth,本地shapefile和美国国家海洋与大气管理局北雷达与地理空间元素集成显示(NOAA RIDGE)雷达覆盖范围的数据WMS。

图1。在hike.chrismichaelis.com上完成的示例
示例应用程序的屏幕快照,左侧显示交互式选项菜单,右侧显示彩色地图的卫星地图

该示例网站还允许用户在地图上绘制远足路线。 用户可以使用Google Gears在浏览器会话之间保存这些路由,也可以将其导出为Keyhole标记语言(KML)。 Google Gears是一个扩展JavaScript的浏览器插件,因此它可以代表页面存储数据,并在会话之间保持持久性。 它还提供了后台JavaScript执行和其他好处。 在此示例中,仅将其用于存储。 请参阅链接到谷歌齿轮开发者网站相关主题的更多信息。

建立网站

第一步是建立将包含地图的网站。 本文中的示例为HTML,CSS和JavaScript内容使用一个单独的文件,以使事情井井有条。 这种结构还有助于将来的维护,并便于以后扩展站点。 由于OpenLayers完全是JavaScript,因此您的页面是纯HTML,不使用服务器端语言。 因此,您可以使用Nginx之类的快速且瘦小的Web服务器来托管它,而不是使用Apache之类的服务器。 由于所有数据都存储在Google Gears中或从Internet来源提取,因此不需要数据库服务器。

jQuery JavaScript库也包含在您的新站点中。 您可以使用jQuery提供的加速JavaScript开发的工具,例如允许快速访问文档对象的选择器 ,例如,使用$('.btnActive').removeClass('btnActive'); 从出现的所有实例中删除btnActive CSS类,而无需专门循环遍历使用getElementsByClassName函数检索的对象。 同样, $('#someID')通过其HTML id属性选择一个元素。

实施OpenLayers

通过下载从的OpenLayers站点的OpenLayers包开始(参见相关主题 )。 将其解压缩到网站位置的子目录中,并将其与HTML文件中的以下行一起包括:

<script type="text/javascript" src="OpenLayers/OpenLayers.js"></script>'

在您JavaScript中,使用jQuery“文档就绪”功能来设置地图。 该函数在onLoad事件之后触发; 并非所有图像和DOM元素都可以在onLoad事件触发时加载并准备就绪,但是可以保证在jQuery“ ready”函数触发时可以加载并准备就绪。 创建一个映射并将其分配给一个变量,如清单1所示。 构造函数的第二个参数允许您传递选项,例如添加到地图的控件,地图的数据投影和显示投影,以及应该可见的最大范围。 maxExtents参数限制查看器可以平移的距离,必须指定它以避免奇怪的行为,尤其是在使用多个数据层时。 忽略它可能会导致诸如根本无法平移或在基础层的顶部严重错位的问题。

清单1.在div mapContainer创建一个OpenLayers映射
$(document).ready(function() {var olMap = new OpenLayers.Map('mapContainer', {controls: [new OpenLayers.Control.MouseDefaults(),],projection: new OpenLayers.Projection('EPSG:900913'),displayProjection: new OpenLayers.Projection('EPSG:4326'),maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34) });
});

OpenLayers中的地图由一个基础层和(可选)几个覆盖(或非基础)层组成。 基本层通常是图像层,例如Google Earth或Virtual Earth; 叠加层通常是用户从MapServer绘制的矢量层或图像。 一次只能有一个基础层处于活动状态。

从多个来源引入数据

通常,Google Earth或Virtual Earth被用作基础层。 这些和许多其他免费的商业数据源都使用球形墨卡托数据投影(由欧洲石油测量集团[EPSG]代码900913标识)。 该投影提供了基于球体模型的地球形状在全球范围内以米为单位测量的数据。 它在大规模上看起来视觉上准确,但是对于本地级别的测量却不准确。 OpenLayers无法自行重新投影数据,因此,地图中包含的所有数据也必须在Spherical Mercator投影中提供。 请参阅链接到球墨卡托信息相关主题的详细信息。

现在,将基础图层添加到地图。 由于一次只能激活一个基础层,因此您可以根据需要添加任意多个基础层,但是默认情况下第一个基础层将处于活动状态。 稍后,您将创建一种在它们之间切换的方法。 清单2显示了用于添加Virtual Earth和Google Earth图层的代码。

清单2.添加Virtual Earth和Google Earth基本层
// Create the Virtual Earth layer
var veSatLayer = new OpenLayers.Layer.VirtualEarth('Virt. Earth', {sphericalMercator: true,'type': VEMapStyle.Aerial,
});
olMap.addLayer(veSatLayer);// Create a Google Earth layer (because it is not first, it is not selected by default)
var googleEarth = new OpenLayers.Layer.Google('Google', {sphericalMercator: true,
});
olMap.addLayer(googleEarth);

下一个要添加的层是NOAA RIDGE WMS。 该服务提供美国的反射率值,通常用于天气预报和云层分析,为您的徒步旅行计划工具提供方便的常规天气指标。 NAD83纬度/经度坐标(EPSG代码4269)中提供了来自此服务的数据,这与您使用球形墨卡托投影的要求不兼容。 因此,您不能将其直接添加到OpenLayers。

而是使用MapServer为您执行重新投影。 有时,您将能够请求Spherical Mercator投影中的数据,而数据提供者会为您投影数据-但不要依赖于此。 无论如何,在您自己的服务器上执行重新投影以减少您对第三方服务器的负载和需求是更礼貌的。 第一步是在Web服务器上安装MapServer(大多数Linux®软件存储库都可用)。 接下来,添加以下行:

<900913> +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs

到Web服务器上文件/ usr / share / proj / epsg的底部。 该行定义了球形墨卡托投影,以便MapServer(及其投影库PROJ4)将知道如何将数据转换为该投影。

接下来,创建一个MapServer映射文件,定义要包含的数据(如清单3所示)。 关键点包括将地图文件的投影设置为EPSG:4326并定义要拉入的WMS图层及其适当的元数据(“ LAYER部分)。 最后,地图文件必须提供一个WEB部分,其中wms_srs值包括要请求的投影-在这种情况下为900913。此设置实质上列出了允许用户请求的投影。 对其他投影的查询会导致错误消息,要求访问者“请求受支持的SRS”(即空间参考系统-本质上是投影)。

清单3.拉入NOAA RIDGE雷达图层的MapServer地图文件,以重新投影到Spherical Mercator
MAPIMAGEQUALITY 95IMAGETYPE pngOUTPUTFORMATNAME pngDRIVER 'GD/PNG'MIMETYPE 'image/png'IMAGEMODE RGBAEXTENSION 'png'ENDPROJECTION"init=epsg:4326"ENDWEBIMAGEPATH '/tmp/'IMAGEURL '/tmp/'METADATA"wms_srs" "EPSG:4326 EPSG:4326 EPSG:3857 EPSG:900913"ENDENDLAYERNAME noaaradarTYPE RASTERCONNECTIONTYPE WMSCONNECTION "http://gis.srh.noaa.gov/arcgis/services/RIDGERadar/MapServer/WMSServer?" METADATA"wms_srs" "EPSG:4326""wms_name" "0""wms_server_version" "1.1.1""wms_format" "image/png"ENDPROJECTION"init=epsg:4629"ENDEND
END

最后,您可以通过参考新创建的地图文件将NOAA RIDGE雷达图层添加到地图中,如清单4所示。

清单4.通过您自己的本地MapServer实例添加NOAA RIDGE雷达WMS
// Add the NOAA RIDGE radar WMS by routing it through our local MapServer instance
// so that it can be re-projected on the fly to Spherical Mercator
var ridgeRadar = new OpenLayers.Layer.WMS('NOAA RidgeRadar','http://hike.chrismichaelis.com/cgi-bin/mapserv.cgi', {layers: 'noaaradar',map: '/var/www/hike.chrismichaelis.com/mapserver/NOAARidgeRadar.map',transparent: true,singleTile: true,visibility: false,srs: 'EPSG:900913'
});
olMap.addLayer(ridgeRadar);

能够提取自己的本地数据(无论是下载的数据还是创建的数据)通常很有用。 您可以通过MapServer进行此操作,类似于添加NOAA RIDGE雷达图层的方式。 清单3中完全创建了MapServer地图文件,但是LAYER部分描述了shapefile而不是WMS,如清单5所示。

清单5. MapServer地图文件的LAYER部分重新投影并提供本地shapefile
LAYERNAME usaroadsTYPE LINEDATA '/var/www/hike.chrismichaelis.com/mapserver/usaroads/roadtrl020.shp'PROJECTION"init=epsg:4326"ENDCLASSNAME 'roadtrl020' STYLEWIDTH 2 COLOR 255 0 0END
END

使用与清单4相同的方法,将roads图层添加到地图上,并用适当的值替换这些layersmap选项。 此时,您将具有一个功能齐全的地图,可从多个来源提取数据,包括默认功能,即使用鼠标进行平移以及使用鼠标滚轮进行放大和缩小。 但是,您仍然无法控制可见的图层或绘制远足路线。 既然地图已经可以使用了,您可以将地图缩放到您感兴趣的区域,而不必将地图缩放到整个美国。 为此,您可以缩放至整数缩放级别(任意固定比例的实验,以查看不同值的影响),然后按纬度和经度定义一个点。 然后,您可以将WGS84纬度和经度(EPSG:4326)的坐标投影(或变换 )到地图的当前投影(球形墨卡托),然后将其缩放。 清单6中说明了此过程。

清单6.缩放到任意纬度和经度位置
// Move to your default location - Pocatello, ID
olMap.zoomTo(10);
var newCenter = new OpenLayers.LonLat(-112.4447222, 42.8713889);
newCenter.transform(new OpenLayers.Projection('EPSG:4326'), olMap.getProjectionObject());
olMap.setCenter(newCenter);

充实功能

没有导航控件,没有完整的地图。 默认情况下,OpenLayers提供基于鼠标滚轮的放大和缩小以及基于鼠标的平移。 您还可以添加地图上的控件-例如:

olMap.addControls(new OpenLayers.Control.NavToolbar);

但是,使用您自己HTML布局来放置和呈现导航控件可提供更大的灵活性,并避免了诸如底层地图数据和导航控件之间的颜色严重冲突之类的问题。 对于比例尺和文本信息覆盖在地图上(例如浅雪白图像和白色比例尺文字),这尤其是一个问题。

在此示例中,您使用简单HTML <img>标签插入图标图像,并使用jQuery将匿名函数附加到该图像。 这些函数可以适当地操纵地图,调用缩放功能或设置地图的中心,如清单7所示。您还可以添加控件以显示鼠标位置和地图比例,并提供更改可见图层的能力(包括选择基础图层)。层)(也如清单7所示)。对于这些控件,您提供一个<div>参数,该参数指示OpenLayers将这些控件呈现到指定HTML <div>元素中,而不是默认值(直接在地图上绘制)。

清单7.添加缩放,平移和图层选择控件以及鼠标位置和比例指示器
// Set up your map GUI controls (vs. using OpenLayers built-in controls)
$('#zoomIn').click(function() {olMap.zoomIn();
});
$('#zoomOut').click(function() {olMap.zoomOut();
});
$('#moveUp').click(function() {// toArray on bounds are in order of left, bottom, right, topolMap.setCenter(new OpenLayers.LonLat(olMap.getCenter().lon, olMap.getExtent().toArray()[3]));
});
$('#moveDown').click(function() {olMap.setCenter(new OpenLayers.LonLat(olMap.getCenter().lon, olMap.getExtent().toArray()[1]));
});
$('#moveLeft').click(function() {olMap.setCenter(new OpenLayers.LonLat(olMap.getExtent().toArray()[0], olMap.getCenter().lat));
});
$('#moveRight').click(function() {olMap.setCenter(new OpenLayers.LonLat(olMap.getExtent().toArray()[2], olMap.getCenter().lat));
});// Add the mouse position to your Controls area
olMap.addControl(new OpenLayers.Control.MousePosition({'div': OpenLayers.Util.getElement('mousePosition'),numDigits: 4
}));// Add a scale indicator to the Controls area
olMap.addControl(new OpenLayers.Control.ScaleLine({'div': OpenLayers.Util.getElement('scaleBar'),geoDesic: true
}));// Add a layer switcher to your Controls area
olMap.addControl(new OpenLayers.Control.LayerSwitcher({'div': OpenLayers.Util.getElement('layerSwitcher'),roundedCorner: false
}));

进阶功能

您希望您的访客能够在屏幕上绘制远足路线。 您可以通过在带有图像标签HTML文件中添加一些按钮来提供此功能: 平移模式绘制模式删除模式保存到KML 。 在JavaScript中,您首先要建立一个包含远足路线的矢量层,并将其添加到地图中。 接下来,创建两个控件: SelectFeatureDrawFeature 。 在SelectFeature控件上,将一个功能添加到featurehighlighted事件中,该事件将删除所选功能,从而将其有效地变为“删除控件”。 将box设置为True并将hover为False可使控件要求绘制与该行相交的框以将其删除,而不是将hover在该框上。 绘制控件更加简单,只需将其添加到地图中即可。

接下来,您使用jQuery向每个新图像“按钮”添加功能。 这些函数的主要目的是在未使用的控件上调用deactivate()并在使用的控件上调用activate() 。 如果同时禁用SelectFeatureDrawFeature控件,则贴图将切换到平移模式。 您还可以通过添加和删除btnActive CSS类来突出显示这些功能中的活动按钮,该类将边框颜色更改为白色。 清单8中显示了所有这些步骤,使您的地图达到了所需的功能级别。

清单8.添加矢量层并设置与之交互的功能
// Create a vector layer that will represent your hiking routes
var hikePaths = new OpenLayers.Layer.Vector("Hike Routes", {strategies: [new OpenLayers.Strategy.Fixed()],style: {strokeWidth: 3,strokeColor: "#00eeee"}
});
olMap.addLayer(hikePaths);// Set up your pan and draw mode toggling and edit controls
featureSelect = new OpenLayers.Control.SelectFeature(hikePaths, {box: true,multiple: true,hover: false,eventListeners: {featurehighlighted: function(feat) {// Remove a feature from the layerhikePaths.destroyFeatures(hikePaths.selectedFeatures);}}
});
featureDraw = new OpenLayers.Control.DrawFeature(hikePaths, OpenLayers.Handler.Path);
olMap.addControls([featureSelect, featureDraw]);$('#drawMode').click(function() {featureSelect.deactivate();featureDraw.activate();$('.btnActive').removeClass('btnActive');$('#drawMode').addClass('btnActive');
});
$('#panMode').click(function() {featureSelect.deactivate();featureDraw.deactivate();$('.btnActive').removeClass('btnActive');$('#panMode').addClass('btnActive');
});
// Set up your delete button - 
// just turns on selection mode, and on select the listener will destroy the feature
$('#deleteMode').click(function() {featureDraw.deactivate();featureSelect.activate();$('.btnActive').removeClass('btnActive');$('#deleteMode').addClass('btnActive');
});

由于许多人使用Google Earth和Google Maps,因此Layer对象的一个​​方便功能是能够导出为KML格式。 您可以使用OpenLayers.Format.KML类来执行此操作,如清单9所示。

清单9.将向量层要素导出为KML格式
// Set up the Save to KML button
$('#saveKML').click(function() {var kmlFormat = new OpenLayers.Format.KML();var newWindow = window.open('', 'KML Export ' + (new Date()).getTime(), "width=300,height=300");newWindow.document.write('<textarea id="kml" style="width: 100%; height: 100%">' +kmlFormat.write(hikePaths.features) + '</textarea>');
});

使用Google Gears存储数据

使用Google Gears可以使您的网站在浏览器会话之间保存远足数据,从而使其更方便,无缝地供休闲使用。 首先,必须实例化OpenLayers.Protocol.SQL.Gears类,并为其指定数据库和表名。 然后,只需将向量层的protocol属性设置为Gears实例。 在初始设置期间,可以使用read()函数从数据库中提取已经存储的功能,然后可以将它们传递到矢量层的addFeatures() ,如清单10所示。

清单10.使用Google Gears添加一个矢量层(与清单8相比-不带Gears的矢量)
// Create a vector layer that will represent your hiking routes
var hikePaths = new OpenLayers.Layer.Vector("Hike Routes", {strategies: [new OpenLayers.Strategy.Fixed()],style: {strokeWidth: 3,strokeColor: "#00eeee"}
});// Because you'll use Google Gears to store hiking routes, set up that protocol:
var gears = new OpenLayers.Protocol.SQL.Gears({saveFeatureState: false,databaseName: 'hikingPaths',tableName: 'hikingPaths'
});
if (!gears.supported()) {alert('Warning: Google Gears is not available. You will not be able to use the hike path drawing tools. Visit http://gears.google.com to install Gears.');
}
else {hikePaths.protocol = gears;var existingGearsData = gears.read();if (existingGearsData.features) hikePaths.addFeatures(existingGearsData.features);
}
// Finally, add the layer
olMap.addLayer(hikePaths);

删除要素后,必须将其从Gears数据库以及图层中删除,因此将其添加到SelectFeature控件的featurehighlighted事件中(请参见清单11)。 同样,添加featureAdded时,请使用DrawFeature控件的featureAdded事件。

清单11.在Gears数据库中添加和删除功能(与清单8相比-不使用Gears管理功能)
// Set up your pan and draw mode toggling and edit controls
featureSelect = new OpenLayers.Control.SelectFeature(hikePaths, {box: true,multiple: true,hover: false,eventListeners: {featurehighlighted: function(feat) {// Remove it from the Gears databaseif (gears.supported()) gears.delete(hikePaths.selectedFeatures);// Remove the actual feature from the layerhikePaths.destroyFeatures(hikePaths.selectedFeatures);}}
});
featureDraw = new OpenLayers.Control.DrawFeature(hikePaths, OpenLayers.Handler.Path, {featureAdded: function(feat) {// Send to the Gears databaseif (gears.supported()) gears.create(feat);}
});
olMap.addControls([featureSelect, featureDraw]);

结论

尽管您在此处建立的网站功能全面,但仍可以进行一些改进:可以更好地显示位置的定位圈,NOAA RIDGE雷达和其他图层的图例或键,用于共享远足的社交网络搭档,和其他可能性。 请参阅相关主题的链接到活生生的例子或下载完整的源代码。 在编写自己的代码时,请参考“ 相关主题”部分中的OpenLayers示例。 祝您映射愉快!


翻译自: https://www.ibm.com/developerworks/opensource/library/os-openlayers/index.html

http://www.lryc.cn/news/2419319.html

相关文章:

  • 图像分割之(五)活动轮廓模型之Snake模型简介
  • shell脚本中四则运算
  • 认识C语言的线程
  • explorer是什么?
  • 一文看懂:网址,URL,域名,IP地址,DNS,2024年最新秀出天际
  • 数据库 超键、候选键、主键、外键
  • 【Flink-HDFS】Call From * to * failed on connection exception: java.net.ConnectException: 拒绝连接;
  • cs服务器(cs索沛服务器)
  • 梯度下降法求解线性回归之python实现
  • ASP.NET运行环境配置
  • 云诺网盘为什么关停了好用的企业网盘有哪些
  • 使用vAPP管理资源
  • Unity - Shader - Projector 高空云层底下透明阴影 - semitransparent shadow
  • Linux 串口RS232/485/GPS 驱动实验(移植minicom)
  • MTK 平台屏蔽 factory mode
  • Redis可视化工具Windows版 Another Redis Desktop Manager 安装与使用_保姆级别
  • 多益网络,面试智商测试题
  • 如果人生太难,就去医院看看
  • Synchronized、lock、volatile、ThreadLocal、原子性总结、Condition
  • 内与外的困惑:找出System进程占用100%CPU的元凶
  • GIS空间分析(四)—— 空间分布类型
  • 如何取消标题栏
  • windows清理系统垃圾bat脚本
  • linux安装zend,linux安装配置Zend Optimizer详解
  • PowerSyncKM 包尔星克 对拷线无法自动链接windows和统信系统
  • GRUB的配置文件的menu.lst的写法(旧版grub)
  • 局域网、以太网、无线局域网学习笔记
  • 关于司南导航全系概况模糊学习记录
  • 数据结构和算法(38)之八皇后问题
  • 优秀网站博客集锦