一个使用Ruby on Rails开发LBS网站的简单实例

news/2024/5/11 0:41:13/文章来源:https://blog.csdn.net/iteye_702/article/details/82096680

一个使用Ruby on Rails开发LBS网站的简单实例

cheungmine

2011-7

这几天一直在学习使用Ruby on Rails(RoR),想建立一个功能全面一点的LBS(Location Based Service)网站。但是对于我这个RoR的初学者(仅有几天时间)来说,毕竟太复杂了。因此本文试图简化原来的设计思路,抛弃一切权限管理,仅仅对数据表中的坐标位置进行插入和更新。也就是,使用表单提交用户坐标位置信息,地图页面定时刷新获取这些信息并显示在地图上。通过这个例子,来熟悉RoR的编程,熟悉ArcGIS Online Map。掌握Ajax在RoR中的一般用法(RJS)。

关键词:Ruby, RoR, MySQL, LBS, Ajax, RJS, ArcGIS Online Map, Dojo

0 安装RubyOnRails

Windows环境下一键安装RubyOnRails开发环境

1)直接点击链接下载:

http://rubyforge.org/frs/download.php/29867/InstantRails-2.0-win.zip

2)或者进入下载页面,选择要安装的版本:http://rubyforge.org/frs/?group_id=904

3)在Windows下安装InstantRails-2.0-win, 解压到无空格的英文路径下即可,如C:\。然后双击C:\InstantRails-2.0-win\InstantRails.exe文件即可启动InstantRails。

4)因为我总是喜欢使用MySQL,因此要手动把文件C:\InstantRails-2.0-win\mysql\bin\libmySQL.dll复制到目录C:\InstantRails-2.0-win\ruby\bin\。这个应该算InstantRails安装包的一个小缺陷吧。

2)开发用到的工具软件

1 创建Rails项目

从InstantRails进入Ruby命令行,输入清单1的命令:

图1:打开Ruby命令行

清单1:创建项目gis

C:\InstantRails-2.0-win\rails_apps>rails -d mysql gis cd gis ruby script/server第1行创建项目,第2行切换到项目中,第3行启动gis服务。点击浏览 http://127.0.0.1:3000/就可以看到网站正确地建立了,如图2:

图2:RoR默认网站

2 创建数据库

从InstantRails进入Ruby命令行:

清单2:创建项目数据库

cd gis gis>mysql -u root –p mysql> create database gis_dev; mysql> create database gis_test; mysql> create database gis; mysql> exit; gis>当 提示Enter Password:时,直接回车。 编辑\rails_apps\gis\config\database.yml文件,修改数据库名:gis_development=>gis_dev,gis_production=>gis。

3 导入数据表(locations)

从InstantRails->Configure->Database (via PhpMyAdmin),使用以下脚本创建gis_dev中的数据表。

清单3:创建gis_dev数据库表locations

drop table if exists locations; create table locations ( id int not null auto_increment, user_id int not null, recv_time timestamp default current_timestamp not null, x_long decimal(12,7) null, y_lat decimal(12,7) null, z_elev decimal(12,3) null, velocity decimal(10,0) null, accel decimal(10,0) null, direction decimal(10,4) null, pitch decimal(10,4) null, roll decimal(10,4) null, battery decimal(3,0) null, confidence decimal(3,0) null, message varchar(200) null, primary key (id) );说明:
user_id:用户id
recv_time:收到信息的时间,这是个数据库自动填充时间的字段
x_long:经度deg
y_lat:纬度deg
z_elev:高度m
velocity:速度m/s
accel:加速度
direction:方向角度
pitch:俯仰角度
roll:倾斜角度
battery:电池电量0-100
confidence:信号强度0-100,似乎用signal更好一些
message:短消息,提供呼叫信息功能
选择数据库gis_dev,在选择SQL标签页,将上面的SQL脚本粘帖到框中,最后按右下角的【执行】按钮。如图3所示:


图3:使用PhpMyAdmin创建数据表

4 生成location模型

进入Ruby命令行,切换到gis目录,输入下面的命令,在一行中输入:
清单4:创建locations Model
ruby script/generate scaffold Location user_id:int recv_time:datetime x_long:decimal y_lat:decimal z_elev:decimal velocity:decimal accel:decimal direction:decimal pitch:decimal roll:decimal battery:decimal confidence:decimal message:string访问地址:http://localhost:3000/locations 应该看到正确的网页。如果上面的脚本执行的结果不正确,我们进入目录,删除它的执行结果,也就是删除下面的文件或目录:
C:\InstantRails-2.0-win\rails_apps\gis\app\controllers\locations_controller.rb
...\gis\app\models\location.rb
...\gis\app\views\locations\
然后重新执行命令。
现在我们可以通过http://localhost:3000/locations/new创建新的location:

图4:创建location的界面

5 建立网站首页

清单5:创建home/index
$ ruby script/generate controller home index $ rm public/index.html$ 代表命令行当前目录提示符:C:\InstantRails-2.0-win\rails_apps\gis>,下同。这样就新建了一个名为home的controller和该controller下的名为index的action。第2行删除默认的首页。然后加入指定的默认首页:
在 config/routes.rb 文件中,将 # map.root :controller => "welcome" 改为:
map.root :controller => "home"
默认首页文件变为:...\gis\app\views\home\index.html.erb。访问地址为:
http://localhost:3000/

我们用预先建好的使用了ArcGIS Online Map的网页替换掉\home\index.html.erb,替换之后的index.html.erb见清单6。

清单6:网站首页文件index.html.erb

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" /> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>LBS Test Map</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.4/js/dojo/dijit/themes/claro/claro.css"> <style type="text/css"> html,body { height:100%; width:100%; margin:0; } body { background-color:#FFF; overflow:hidden; font-family:"Trebuchet MS"; } #mainWindow { width:100%; height:100%; margin:0px; padding:0; } #header { border:solid 0px #FFF; border-bottom:1px solid #AEAEAE; background-color:#EEF2FB; color:#CD853F; font-size:10pt; text-align:center; height:80px; margin:0px; padding:0; } #subheader { font-size:small; color:#CD853F; } #rightPane { background-color:#FFF; border:none; width:300px; overflow:hidden; margin:0px; padding:0; } #mapDiv { background-color:#FFF; border:solid 1px #AEAEAE; margin:0px; padding:0; } #measurementPaneDiv { background-color:#FFF; border:solid 1px #B8B8B8; height:130px; overflow:hidden; margin:0px; padding:0; } #measurementDiv { background-color:#FFF; font-size:10pt; height:100%; overflow:hidden; margin:0px; padding:0; } </style> <script type="text/javascript"> var djConfig = { parseOnLoad: true }; </script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"> </script> <script type="text/javascript"> dojo.require("dijit.dijit"); // optimize: load dijit layer dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("esri.map"); dojo.require("esri.dijit.Measurement"); dojo.require("esri.dijit.Scalebar"); dojo.require("esri.toolbars.draw"); dojo.require("esri.dijit.OverviewMap"); var map, spatialRef, initExtent; // init on load function initGCS_WGS_1984() { // 4326 = GCS_WGS_1984 spatialRef = new esri.SpatialReference({wkid:4326}); // china extent initExtent = new esri.geometry.Extent(65, 9, 145, 55, spatialRef); map = new esri.Map("mapDiv"); map.setExtent(initExtent); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); } // init on load function initWGS_1984_Web_Mercator_Auxiliary_Sphere() { // 102100 = WGS_1984_Web_Mercator_Auxiliary_Sphere spatialRef = new esri.SpatialReference({"wkid": 102100}); // china extent initExtent = new esri.geometry.Extent({ "xmin":-32971876.5210848, "ymin":2044843.3806844242, "xmax":-23921732.37212246, "ymax":7127600.013534156, "spatialReference":{"wkid":102100} }); map = new esri.Map("mapDiv", {extent:initExtent, wrapAround180:true}); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); var referenceUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer"; var referenceLayer = new esri.layers.ArcGISTiledMapServiceLayer(referenceUrl); map.addLayer(referenceLayer); } // resize map function resizeMap() { var resizeTimer; clearTimeout(resizeTimer); resizeTimer = setTimeout( function(){map.resize(); map.reposition();}, 500 ); } function initToolbar(map) { //define a new line symbol and point symbol to use for measure tools var pms = new esri.symbol.PictureMarkerSymbol("images/flag.png", 24, 24); pms.setOffset(9,11); var sls = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DOT, new dojo.Color([255,0,0,.55]), 4); var measurement = new esri.dijit.Measurement({ map: map, lineSymbol:sls, pointSymbol:pms }, dojo.byId('measurementDiv') ); measurement.startup(); measurement.setTool("area", true); } // show map on load dojo.addOnLoad(initGCS_WGS_1984); // dojo.addOnLoad(initWGS_1984_Web_Mercator_Auxiliary_Sphere); </script> </head> <body class="claro"> <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"> <div id="header" dojotype="dijit.layout.ContentPane" region="top"> <h1>A Test for RoR with ArcGIS Online Map</h1> </div> <!-- header --> <div id="mapDiv" dojotype="dijit.layout.ContentPane" region="center"> </div> <!-- mapDiv --> <div id="rightPane" dojotype="dijit.layout.BorderContainer" region="right" gutters="false"> <div id="admin_div" dojotype="dijit.layout.ContentPane" style="height:100%;" region="center"> </div> <!-- admin_div --> <div id="measurementPaneDiv" dojotype="dijit.layout.ContentPane" region="bottom"> <div id="measurementDiv" style="height:100%;"></div> </div> <!-- measurementPaneDiv --> </div> <!-- rightPane --> </div> <!-- mainWindow --> </body> </html>本文把HTML代码、css、js放在一起,是为了说明上的方便,实际当中应分开放置。关于如何使用ArcGIS Online Map和ArcGIS JSAPI编程请参考下面的网址:

http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi_start.htm
此时我们再浏览http://localhost:3000/,显示如图5所示:

图5:网站(gis)的首页

6 用RJS查询locations

我的设想是设置一个定时器,不断地查询locations表,把获得的记录显示右边的空白处(<div id="admin_div" ></div>),同时把坐标点显示在地图(map)上。当我们访问http://localhost:3000/locations,会显示locations数据表的全部信息,因此我们就想办法把这个表显示在admin_div处,这就需要引入Ajax,或者称为RJS(Ruby-generated JavaScript)的东西。请参考我转载的一篇文章(RubyOnRails with Ajax),那里面详细讨论了RJS技术的实现原理和方法。

6.1 添加定时器查询数据库

为此我们首先添加一个链接到清单6中(\home\index.html.erb),当用户点击这个链接,admin_div就显示查询的结果。添加链接之后的代码如下:

清单7:修改index.html.erb,红色粗体的部分是我新增的代码

<div id="header" dojotype="dijit.layout.ContentPane" region="top"> Click this link to show the current <%= link_to_remote "locations", :update => 'admin_div', :url => {:controller=>"locations", :action =>"list_by"} %>. </div> <!-- header -->上面清单7代码中,:url => {:controller=>"locations", :action =>"list_by"}指明链接的位置:controller和action。我们知道在locations controller中并没有list_by这个action,我手动把这个list_by添加到locations_controller.rb中,不要修改其他任何部分,见清单8:

清单8:给locations_controller.rb添加list_by,红色粗体的部分是我新增的代码class LocationsController < ApplicationController # GET /locations # GET /locations.xml def index @locations = Location.find(:all) respond_to do |format| format.html # index.html.erb format.xml { render :xml => @locations } end end # add by me def list_by redirect_to :action => "index" end
另外为了支持RJS,我们还需要把<%= javascript_include_tag :defaults %>添加到index.html.erb中:

清单9:添加RJS声明

... </style> <%= javascript_include_tag :defaults %> <script type="text/javascript"> ... 现在我们浏览http://localhost:3000/并点击 locations链接后,界面显示如下:

图6:增加了RJS后的首页

到目前为止,locations链接是您见到的惟一触发器。Ajax 还有许多其他的可用武器,一些由用户驱动,而另一些由程序事件驱动,如时钟。它是一个像闹钟一样并不需要用户干预的东西。可以用 Ajax 的 periodically_call_remote 方法定期更新时钟。更改 index.html.erb 代码如清单10(仅仅修改红色黑体部分):

清单10:修改index.html.erb,增加periodically_call_remote

<div id="header" dojotype="dijit.layout.ContentPane" region="top"> <h1>A Test for RoR with ArcGIS Online Map</h1> <%= periodically_call_remote :update => 'admin_div', :url => {:controller=>"locations", :action =>"list_by"}, :frequency => 3.0 %> </div> <!-- header -->
重新浏览http://localhost:3000/,现在发现admin_div被每3秒自动更新一次。此时我们打开一个新的浏览器并定位到http://localhost:3000/locations/new,创建一个新的location,可以在http://localhost:3000/页面看到Listing locations发生了变化,我们新增加的记录被添加到了底部:

图7:自动更新Listing locations

接下来的工作主要是页面的重构和美化。说实在的,这的确耗去了我很多时间。重构之后的页面改变了某些div的id,对部分网页代码也做了调整。最终的成果就是看起来如图8的样子:

图8:最终的gis主页

6.2 为定时器添加启动(Start Monitor)和暂停(StopMonitor)的方法

我们设想用户可以控制periodically_call_remote定时器的启动和停止。因此需要修改一下Ruby代码。修改后的代码如下:

清单11:控制periodically_call_remote定时器的启动和停止代码

<head> ...... <%= javascript_include_tag :defaults %> <script type="text/javascript"> ...... var myMonitor = true; var myUpdater = null; PeriodicalExecuter.prototype.resume = function(){ if(!this.timer) this.registerCallback(); }; function startMonitor() { if (myUpdater != null) { myUpdater.resume(); } } function stopMonitor() { if (myUpdater != null) { myUpdater.stop(); } } </script> </head> <body class="claro"> <%= periodically_call_remote( :variable => "myUpdater", :condition => "myMonitor == true", :update => "locations_div", :url => {:controller=>"locations", :action =>"list_by"}, :frequency => 5, :complete => "new Effect.Highlight('locations_div');refreshLocations(dojo.byId('tb_users'));") %> <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"> ...... <div id="locations_div" dojotype="dijit.layout.ContentPane" region="center"> </div> <!-- locations_div --> ...... </div> </body>

:variable => "myUpdater", 指明new PeriodicalExecuter返回变量名。
:condition => "myMonitor == true", 指明触发器回调函数运行的条件。
:update => "locations_div", 指明要更新的div id。就是上文的(admin_div),我改了名字。
:url => {:controller=>"locations", :action =>"list_by"}, 指明控制器和反应器名称。
:frequency => 5, 指定定时器间隔5秒
:complete => "...." 指明链接加载完毕onComplete执行的代码,我们的JavsScript代码可以放在这里。

我增加了下面的代码:
PeriodicalExecuter.prototype.resume = function(){
if(!this.timer)
this.registerCallback();
};
因为PeriodicalExecuter是...\gis\public\javascripts\prototype.js中的JS对象。PeriodicalExecuter只有stop方法,为此我们需要增加了启动定时器的重启方法resume()。
比较清单11中蓝色的代码和运行后查看浏览器源代码中的显示(我做了排版编辑):

清单12:查看浏览器源代码

myUpdater = new PeriodicalExecuter( function(){ if (myMonitor == true) { new Ajax.Updater( 'locations_div', '/locations/list_by', { asynchronous:true, evalScripts:true, onComplete:function(request) { new Effect.Highlight('locations_div'); refreshLocations(dojo.byId('tb_users')); }, parameters:'authenticity_token=' + encodeURIComponent('314268a80fbdca6f758e7bd120507c12a10c4698') } ); } }, 5 );只要能操作 PeriodicalExecuter的实例myUpdater和控制boolean变量myMonitor就可以 控制periodically_call_remote定时器。为此我们需要修改Ruby产生的默认代码,这个过程称为override。默认的代码没有返回myUpdater,因此我们需要修改默认的代码。找到这个文件:

C:\InstantRails-2.0-win\rails_apps\gis\app\helpers\application_helper.rb。

修改application_helper.rb文件以和下面的清单13一致:

清单13:重载periodically_call_remote,以支持返回变量

# Methods added to this helper will be available to all templates in the application. module ApplicationHelper def periodically_call_remote(options = {}) variable = options[:variable] ||= 'poller' frequency = options[:frequency] ||= 10 code = "#{variable} = new PeriodicalExecuter(function(){#{remote_function(options)}}, #{frequency})" javascript_tag(code) end end 最后,我们调用myUpdater.stop()停止定时器,调用myUpdater.resume()重启定时器。示例主页中,表格定时会变黄色,就是定时器启动的情况下,Ajax代码: new Effect.Highlight('locations_div')
作用的效果。当我们按Draw Point按钮时,我们会发现浏览器上部出现了一个输入表:

图9:locations/new的RJS实现

这又是另外一个Ajax的例子。读者可以自己在主页的源代码(index.html.erb)中揣摩(http://localhost:3000/locations/new)。


7 ArcGIS JavaScriptAPI编程


7.1 ArcGIS Online地图服务

本文用的地图是ESRI的在线地图服务的地图数据。使用这个服务不需要客户端装任何东西。ArcGIS Online Map Server使用REST(Representational State Transfer)的对象访问协议。REST,表述性状态转移,只要使用网址,就可以很容易地创建、发布和使用“REST风格”的网络服务。相比REST之前的简单对象访问协议(SOAP),REST是轻量级的,使用简便、灵活。REST是各层次开发者利用ArcGISServer创建自定义应用的最简便方法。其实质是用URI(统一的资源标识,它是以某种统一的标准化的方式标识资源的一串字符串)描述互联网上的资源,所以没有开发工具的限制。

使用ArcGIS JSAPI可以快速的创建交互式的地图RIA应用——RIA(Rich Internet Applications)富互联网应用,具有高度互动性、丰富用户体验以及功能强大的客户端。基于REST API,我们可以为用户提供查询,显示要素等服务。利用叠加GP服务,可以为用户提供专业的分析结果。

7.2 如何显示一个ArcGIS Online地图

更多的资源请参考:http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi_start.htm

本文的例子在:C:\InstantRails-2.0-win\rails_apps\gis\app\views\home\index.html.erb。

1)创建一个文本文件,复制下面的代码到文件中,然后文件保存为:arcgis-demo.html。

清单14:arcgis-demo.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ArcGIS Online Map Simplest Demo - cheungmine</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.4/js/dojo/dijit/themes/claro/claro.css"> <style type="text/css"> html,body { height:100%; width:100%; margin:0; } body { background-color:#FFF; overflow:hidden; font-family:"Trebuchet MS"; } #mainWindow { width:100%; height:100%; margin:0px; padding:0; } #mapDiv { background-color:#FFF; border:solid 1px #AEAEAE; margin:0px; padding:0; } </style> <%= javascript_include_tag :defaults %> <script type="text/javascript"> var djConfig = { parseOnLoad: true }; </script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"> </script> <script type="text/javascript"> dojo.require("dijit.dijit"); // optimize: load dijit layer dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("esri.map"); dojo.require("esri.dijit.Scalebar"); dojo.require("esri.toolbars.draw"); dojo.require("esri.dijit.OverviewMap"); var map, spatialRef, initExtent; // init on load function initGCS_WGS_1984() { // 4326 = GCS_WGS_1984 spatialRef = new esri.SpatialReference({wkid:4326}); // china extent: Longitude(65~145), Latitude(9~55) initExtent = new esri.geometry.Extent(65, 9, 145, 55, spatialRef); map = new esri.Map("mapDiv"); map.setExtent(initExtent); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); } // init on load function initWGS_1984_Web_Mercator_Auxiliary_Sphere() { // 102100 = WGS_1984_Web_Mercator_Auxiliary_Sphere spatialRef = new esri.SpatialReference({"wkid": 102100}); // china extent initExtent = new esri.geometry.Extent({ "xmin":-32971876.5210848, "ymin":2044843.3806844242, "xmax":-23921732.37212246, "ymax":7127600.013534156, "spatialReference":{"wkid":102100} }); map = new esri.Map("mapDiv", {extent:initExtent, wrapAround180:true}); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); var referenceUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer"; var referenceLayer = new esri.layers.ArcGISTiledMapServiceLayer(referenceUrl); map.addLayer(referenceLayer); } // resize map function resizeMap() { var resizeTimer; clearTimeout(resizeTimer); resizeTimer = setTimeout( function(){map.resize(); map.reposition();}, 500 ); } // show map on load // dojo.addOnLoad(initGCS_WGS_1984); dojo.addOnLoad(initWGS_1984_Web_Mercator_Auxiliary_Sphere); </script> </head> <body class="claro"> <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"> <div id="mapDiv" dojotype="dijit.layout.ContentPane" region="center"> </div> <!-- mapDiv --> <!-- mainWindow --> </body> </html>2)使用浏览器打开这个文件,就可以看到Web地图了。


图10:arcgis-demo.html展示的ArcGIS Online Map

7.3 ArcGIS JSAPI 使用了Dojo这个著名的Ajax开源JavaScript库

为什么是dojo?
1)Dojo宽松的使用许可
2)Dojo功能全面,事件设计模式、矢量图形支持、显示效果、widgets、Ajax、JSON等都是ArcServer客户端开发所需要的,并且Dojo利于扩展,方便Mashup应用
3)客户端有丰富的图表

参考:
http://dojotoolkit.org

http://dojocampus.org

8 安装和使用示例代码

本文的示例代码下载地址:http://download.csdn.net/source/3459994

8.1 安装并配置RoR环境

1) 下载InstantRails-2.0-win.zip:

http://rubyforge.org/frs/download.php/29867/InstantRails-2.0-win.zip

2) 解压到 C:\ 下. 主目录名默认为:C:\InstantRails-2.0-win\InstantRails.exe

3) 此步可以忽略,下面的cpy-mysql-db.bat批处理中执行了这个过程:复制libmySQL.dll. 开始->运行 cmd:

copy C:\InstantRails-2.0-win\mysql\bin\libmySQL.dll C:\InstantRails-2.0-win\ruby\bin\

4) 运行 C:\InstantRails-2.0-win\InstantRails.exe, 如果提示Apache端口被占用, 如下图:

图11:Apache端口错误消息

编辑修改下面的文件:

C:\InstantRails-2.0-win\apache\conf\httpd.conf
将80改为81
Listen 80=>81
...
Port 80=>81

8.2 部署gis网站

1) 把gis.rar解压到 C:\InstantRails-2.0-win\rails_apps\ 目录下, 运行下面的批处理文件:


C:\InstantRails-2.0-win\rails_apps\gis\cpy-mysql-db.bat
这样我们的gis站点和MySQL数据库就部署好了.

2) 启动gis网站. 运行 C:\InstantRails-2.0-win\InstantRails.exe


图12:InstantRails主界面

选择[I.]->Rails Applications->Manage Rails Application..., 弹出下面的对话框,左边勾选 gis 检查框, 右边按 Start with Mongrel 启动gis网站服务。

图13:Rails程序管理器

3) 打开浏览器, 输入网址 http://localhost:3000/http://127.0.0.1:3000/,即可看到网站主页.


图14:gis网站主页

8.3 使用gis网站

打开2个浏览器A和B, 都定位到网站主页: http://127.0.0.1:3000/

1) 浏览器A(IE7)模拟GPS点生成过程

按浏览器A的页面上部的 Draw Point 按钮, 然后在地图上的某个位置处点击, 再按页面上部的 Sumbit 按钮, 即把当前的记录提交到了后台数据库, 过几秒, 就可以看到这个黑点出现在地图上的点击处, 同时右边的表格中多了一条记录.

图15:模拟生成GPS点的过程

2)浏览器B(FireFox5)模拟监控者的画面

对于浏览器A中的操作, 5秒之后都会出现在浏览器B的主页上. 反之亦然.


图16:模拟监控者届面

9 关于Ruby、RoR的一些展望

本文写作时采用的是Ruby1.8.6和Rails2.0.2。显然这个版本已经过时了。但是因为InstantRails的存在,这个版本对于初学者特别合适。

Ruby是一门特别简单而功能强大的解释型语言。它一经推出,即风靡了整个业界。它是一个解释型语言。在脚本语言家族中,早期的Ruby版本,据说速度较慢。对于高性能、高度保密的需求上,可以用C语言的库来扩展它。2009年1月30日,ruby 1.9.1的正式版本如期发布! 1.9.1是ruby 1.9系列以来的第一个production ready的版本,这也标志着Ruby社区从此迈向了1.9的时代。ruby 1.9是ruby发展历史上的一个里程碑版本:

1)ruby 1.9首次引入字节码即时编译技术,可以大大提高ruby本身的性能。根据之前的综合评测来看,1.9的性能大约是1.8.6的三倍左右,性能追上了Python。

2)ruby 1.9正式支持内核多线程机制,可以大大提高ruby作为服务端程序的并发处理能力。

3)ruby 1.9还引入了纤程这样的多任务并发处理机制,提供了轻量级并发处理能力。

因此,Ruby的一门很有潜力的新语言。Ruby on Rails(RoR)是近几年开始流行的新一代Web开发框架语言,其易用、敏捷的特性受到很多Web开发人员的瞩目。Rails是基于Ruby之上的开发动态Web的首选框架。在Web2.0时代,RoR是快速开发RIA应用的首选语言。RoR尤其适合于快速架构跨平台的各种类型的Web网站、开发云计算平台的RIA入口等等。

Ruby可以用于书写RoR的服务页面程序;也可以用Ruby脚本管理网络、服务器;Ruby也用于对象胶,组合各种系统服务、功能模块等等。

RoR结合Nginx(Nginx已经成为世界第三大Web服务器)在Linux平台上,可以以极小的代价开发和部署支持海量并发请求的、高性能的、可扩展的网站和云计算服务。利用C语言扩展Ruby后台模块,利用多核、异步、线程池等技术,可以满足高可靠性、可扩展性、服务逻辑隐藏等需求,同时使实现异步的、长时间、高负载的Web后台运算或云计算服务成为可能。

附录1: gis 主页源代码

清单15: ...\gis\app\views\home\index.html.erb
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" /> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>RoR with LBS Demo - cheungmine</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.4/js/dojo/dijit/themes/claro/claro.css"> <style type="text/css"> html,body { height:100%; width:100%; margin:0; } body { background-color:#FFF; overflow:hidden; font-family:"Trebuchet MS"; } #mainWindow { width:100%; height:100%; margin:0px; padding:0; } #header { border:solid 0px #FFF; border-bottom:1px solid #AEAEAE; background-color:#FFF; color:#CD853F; font-size:10pt; text-align:center; height:90px !important; height:80px; margin-bottom:3px; padding:0; } #new_location_div { border:solid 0px #FFF; background-color:#FFF; color:#CD853F; font-size:10pt; text-align:center; overflow:hidden; height:60px; margin-left:10px; padding:0; } #menusDiv { border:solid 0px #FFF; background-color:#FFF; color:#CD853F; font-size:10pt; text-align:right; height:30px; overflow:hidden; margin-right:20px; padding:0; } #rightPane { background-color:#FFF; border:solid 1px #AEAEAE; width:400px; overflow:hidden; margin:0px; padding:0; } #mapDiv { background-color:#FFF; border:solid 1px #AEAEAE; margin:0px; padding:0; } #measurementPaneDiv { background-color:#FFF; border:solid 0px #B8B8B8; height:130px; overflow:hidden; margin:0px; padding:0; display:yes; } #measurementDiv { background-color:#FFF; border:solid 0px #B8B8B8; font-size:10pt; height:100%; overflow:hidden; margin:0px; padding:0; } #locations_div { background-color:#FFF; height:100%; border: 0; margin: 0; padding:0; } #tb_users { border-collapse:collapse; } #tb_users th { font-size:8pt; white-space:nowrap; } #tb_users td { border:1px solid #EEF2FB; font-size:8pt; white-space:nowrap; } #new_users { border-collapse:collapse; height:48px; } #new_users th { font-color:#000; font-size:8pt; white-space:nowrap; height:16px; margin: 0; padding:0; } #new_users td { border:0px solid #EEF2FB; font-size:8pt; white-space:nowrap; height:22px; margin: 0; padding:0; } a { text-decoration: none; } h2, h3 { margin: 0 0 20px; text-shadow: 2px 2px #fff; } h2 { font-size: 28px; } h3 { font-size: 22px; } pre { background: #fff; width: 460px; padding: 10px 20px; border-left: 5px solid #ccc; margin: 0 0 20px; } input { margin: 0; padding: 0; } .button { padding: 3px 5px; display: inline; background: #ABC url(button.png) repeat-x bottom; border: none; color: #fff; cursor: pointer; font-weight: bold; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; text-shadow: 1px 1px #666; } .button:hover { background-position: 0 center; } .button:active { background-position: 0 top; position: relative; top: 1px; padding: 3px 5px 2px; } .button.red { background-color: #e50000; } .button.purple { background-color: #9400bf; } .button.green { background-color: #58aa00; } .button.orange { background-color: #ff9c00; } .button.blue { background-color: #2c6da0; } .button.black { background-color: #333; } .button.white { background-color: #fff; color: #000; text-shadow: 1px 1px #fff; } .button.small { font-size: 75%; padding: 3px 7px; } .button.small:active { padding: 4px 7px 2px; background-position: 0 top; } .button.large { font-size: 125%; padding: 7px 12px; } .button.large:active { padding: 8px 12px 6px; background-position: 0 top; } </style> <%= javascript_include_tag :defaults %> <script type="text/javascript"> var djConfig = { parseOnLoad: true }; </script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"> </script> <script type="text/javascript"> dojo.require("dijit.dijit"); // optimize: load dijit layer dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("esri.map"); dojo.require("esri.dijit.Measurement"); dojo.require("esri.dijit.Scalebar"); dojo.require("esri.toolbars.draw"); dojo.require("esri.dijit.OverviewMap"); var map, toolbar, spatialRef, initExtent, defaultPointSymbol, defaultLineSymbol, defaultFillSymbol; // init on load function initGCS_WGS_1984() { // 4326 = GCS_WGS_1984 spatialRef = new esri.SpatialReference({wkid:4326}); // china extent initExtent = new esri.geometry.Extent(65, 9, 145, 55, spatialRef); map = new esri.Map("mapDiv"); map.setExtent(initExtent); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); } // init on load function initWGS_1984_Web_Mercator_Auxiliary_Sphere() { // 102100 = WGS_1984_Web_Mercator_Auxiliary_Sphere spatialRef = new esri.SpatialReference({"wkid": 102100}); // china extent initExtent = new esri.geometry.Extent({ "xmin":-32971876.5210848, "ymin":2044843.3806844242, "xmax":-23921732.37212246, "ymax":7127600.013534156, "spatialReference":{"wkid":102100} }); map = new esri.Map("mapDiv", {extent:initExtent, wrapAround180:true}); dojo.connect(map, 'onLoad', function(map) { var scalebar = new esri.dijit.Scalebar({map: map, scalebarUnit: "metric"}); dojo.connect(dijit.byId('mapDiv'), 'resize', resizeMap); initToolbar(map); // add the overview map var overviewMapDijit = new esri.dijit.OverviewMap({map: map, visible:false}); overviewMapDijit.startup(); } ); var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"; var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl); map.addLayer(basemap); var referenceUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer"; var referenceLayer = new esri.layers.ArcGISTiledMapServiceLayer(referenceUrl); map.addLayer(referenceLayer); } // resize map function resizeMap() { var resizeTimer; clearTimeout(resizeTimer); resizeTimer = setTimeout( function(){map.resize(); map.reposition();}, 500 ); } function initToolbar(map) { // create symbol for drawing defaultPointSymbol = new esri.symbol.SimpleMarkerSymbol( esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 11, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255,255,255]), 2), new dojo.Color([10,10,10, 1])); // create toolbar toolbar = new esri.toolbars.Draw(map); dojo.connect(toolbar, "onDrawEnd", addLocation); //define a new line symbol and point symbol to use for measure tools var pms = new esri.symbol.PictureMarkerSymbol("images/flag.png", 24, 24); pms.setOffset(9,11); var sls = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DOT, new dojo.Color([255,0,0,.55]), 4); var measurement = new esri.dijit.Measurement({ map: map, lineSymbol:sls, pointSymbol:pms }, dojo.byId('measurementDiv') ); measurement.startup(); // measurement.setTool("distance", true); } // show map on load dojo.addOnLoad(initGCS_WGS_1984); // dojo.addOnLoad(initWGS_1984_Web_Mercator_Auxiliary_Sphere); // add location to database when onDrawEnd fired function addLocation(geometry) { dojo.byId("inLong").value = geometry.x; dojo.byId("inLat").value = geometry.y; var type = geometry.type; if (type === "point" || type === "multipoint") { symbol = toolbar.markerSymbol; } else if (type === "line" || type === "polyline") { symbol = toolbar.lineSymbol; } else { symbol = toolbar.fillSymbol; } map.graphics.add(new esri.Graphic(geometry, symbol)); } function isValidValue(val) { if (val==null || val=="") return false; return true; } // user location class function userLocation(user_id, recv_time, x_long, y_lat, z_elev, message) { this.valid = false; this.id = user_id; this.recv = recv_time; this.x = x_long; this.y = y_lat; this.z = z_elev; this.msg = message; if (isValidValue(this.id) && isValidValue(this.recv) && isValidValue(this.x) && isValidValue(this.y)) { this.valid = true; } } // add user location to map function addMapGraphics(user) { if (!user.valid) return; var pt = new esri.geometry.Point(user.x, user.y, spatialRef); var graphic = new esri.Graphic(pt, defaultPointSymbol); map.graphics.add(graphic); } // refresh locations function refreshLocations(tb) { // clear old first clearMapGraphics(); // we get table object and get its all tds var rows=tb.rows; for(i=1; i<rows.length; i++){ cols = rows[i].cells; var user = new userLocation(cols[0].innerHTML, cols[1].innerHTML, cols[2].innerHTML, cols[3].innerHTML, cols[4].innerHTML, cols[12].innerHTML); addMapGraphics(user); } } function clearMapGraphics() { map.graphics.clear(); } var myMonitor = true; var myUpdater = null; PeriodicalExecuter.prototype.resume = function(){ if(!this.timer) this.registerCallback(); }; function startMonitor() { if (myUpdater != null) { myUpdater.resume(); } } function stopMonitor() { if (myUpdater != null) { myUpdater.stop(); } } </script> </head> <body class="claro"> <%= periodically_call_remote( :variable => "myUpdater", :condition => "myMonitor == true", :update => "locations_div", :url => {:controller=>"locations", :action =>"list_by"}, :frequency => 5, :complete => "new Effect.Highlight('locations_div');refreshLocations(dojo.byId('tb_users'));") %> <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"> <div id="header" dojotype="dijit.layout.ContentPane" region="top"> <div id="new_location_div" dojotype="dijit.layout.ContentPane" region="center"> </div> <div id="menusDiv" dojotype="dijit.layout.ContentPane" region="bottom"> <a href="#" class="button green" οnclick="startMonitor();">Start Monitor</a> <a href="#" class="button red" οnclick="stopMonitor();">Stop Monitor</a> <%= link_to_remote("Draw Point", { :update => "new_location_div", :url => {:controller=>"locations", :action =>"new"}, :complete => "toolbar.activate(esri.toolbars.Draw.POINT);" }, { :class => "button orange"} ) %> <a href="#" class="button orange" οnclick="clearMapGraphics();">Clear Graphics</a> </div> </div> <!-- header --> <div id="mapDiv" dojotype="dijit.layout.ContentPane" region="center"> </div> <!-- mapDiv --> <div id="rightPane" dojotype="dijit.layout.BorderContainer" region="right" gutters="false" splitter="true"> <div id="locations_div" dojotype="dijit.layout.ContentPane" region="center"> </div> <!-- locations_div --> <div id="measurementPaneDiv" dojotype="dijit.layout.ContentPane" region="bottom"> <div id="measurementDiv" style="height:100%;"></div> </div> <!-- measurementPaneDiv --> </div> <!-- rightPane --> </div> <!-- mainWindow --> </body> </html>

附录2: 参考文献

1) AgileWebDevelopmentWithRails-3rdEd.pdf
2) building_dynamic_web_2.0_websites_with_ruby_on_rails.pdf
3) OReilly.Ajax.on.Rails.Dec.2006.chm
4) Enterprise Integration with Ruby - A Pragmatic Guide.pdf
5) OReilly.Dojo.The.Definitive.Guide.Jun.2008.pdf
6) ArcGIS JavaScript API开发—初级篇_白明.pdf


全文完

作者:张亮

2011年7月21日深夜于上海

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_813719.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[网站公告]23:00-05:00阿里云SLB升级会造成4-8次每次10秒的闪断

大家好&#xff0c;阿里云将于今天夜里&#xff08;7月29日23:00-7月30日05:00&#xff09;对负载均衡服务&#xff08;SLB&#xff09;进行升级操作&#xff0c;升级期间我们使用的SLB实例会有4-8次的闪断&#xff0c;每次闪断时间10秒左右。闪断期间会造成网站不能正常访问&a…

网站安全通用防护代码(C#版本源码提供)

每一个开发者都会意识到&#xff0c;网站发布之前&#xff0c;需要进行安全检查。 那么如何拦截攻击者注入恶意代码&#xff1f;如何防御诸如跨站脚本攻击&#xff08;XSS&#xff09;、SQL注入攻击等恶意攻击行为&#xff1f; 针对目前常见的一些安全问题&#xff0c;结合目前…

网站策划方案写作、演示标准

一份成功的网站策划方案是赢得订单的重要砝码&#xff0c;如何写一份令客户心动的网站策划方案则需要下苦功夫。《网站策划方案写作、演示标准》主要分为7个部分&#xff0c;希望对您有帮助&#xff1a;1. 网站策划方案的价值——内容重点阐述了解决方案能给客户带来什么价值&a…

网站策划方案写作、演示标准

一份成功的网站策划方案是赢得订单的重要砝码&#xff0c;如何写一份令客户心动的网站策划方案则需要下苦功夫。《网站策划方案写作、演示标准》主要分为7个部分&#xff0c;希望对您有帮助&#xff1a;1. 网站策划方案的价值——内容重点阐述了解决方案能给客户带来什么价值&a…

理解 Ajax 及其工作原理,构建网站的一种有效方法

理解 Ajax 及其工作原理&#xff0c;构建网站的一种有效方法 Ajax 由 HTML、JavaScript™ 技术、DHTML 和 DOM 组成&#xff0c;这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家&#xff0c;他演示了这些技术如何协同工作 —— …

Android技术开发 必备网站及使用工具

【前言】工欲善其事&#xff0c;必先利其器。搞开发多年了&#xff0c;会收藏一些干货网站和工具&#xff0c;辅助开发&#xff0c;提高开发效率。下面一次性分享给大家。喜欢的朋友们点个赞吧。 说明&#xff1a;这些是我收藏的网站&#xff0c;感觉还是不错的&#xff0c;仅仅…

webgis本地部署之在IIS6,7中部署ASP.NET网站

阅读目录 开始查看web.config文件在IIS中创建网站IIS6 添加扩展名映射IIS6 无扩展名的映射目录的写入权限SQL SERVER的配置在IIS7中部署ASP.NET程序80端口和域名 在我的第一篇博客中&#xff0c;我发布过一个示例项目&#xff0c; 主要演示了我的我的AJAX框架和我的通用数据访问…

从外网访问内网本机的网站实现方法

这是一个比较古老的话题了。一般懂得搭建网站的朋友&#xff0c;应该都会有分享自己小站的冲动。一来可以展示自己的作品&#xff0c;二来也可以方便别人看看网站&#xff0c;提提意见。呵呵。 鉴于网上类似的详细教程真的很少&#xff0c;也许是问题太简单了吧。但仍然有不少…

关于12306网站图形验证码的猜想

以前一直以为12306的图形验证码是根据普通验证码识别规则&#xff0c;只不过是加上了变态的不清晰低像素图片而已。 然后F12查看了一下网络请求&#xff0c;它的验证码规则&#xff0c;远远不是我之前我想的那么简单的。 很久以前一直单纯的以为&#xff0c;可以通过图片的识别…

linux查看网站内容,linux如何查看文件有多少行内容_网站服务器运行维护

如何查看linux系统是多少位的_网站服务器运行维护查看linux操作系统位数的方法&#xff1a;1、执行【uname -a】命令&#xff0c;如果输出i686&#xff0c;表示操作系统是32位的&#xff0c;如果输出x86_64&#xff0c;表示操作系统是64位的&#xff1b;2、执行【file /lib/sys…

linux 安装软件_介绍一个linux各软件安装教程网站linuxize

前言相信有很多开发者安装linux系统软件时都会根据不同的发行版本去百度不同软件的安装步骤&#xff0c;但有时候可能会出现读者根据博主的安装步骤进行却出现了无法安装成功的情况&#xff0c;其实我作为一名读者有时也会出现这样的情况&#xff0c;一般都会再去参考其它文章对…

企业网站 源码 服务邮箱:_企业邮箱服务有哪些?外贸公司邮箱申请哪个好?

公司购买企业邮箱&#xff0c;免不了对比&#xff0c;评判一个企业邮箱的标准也是多维度的。企业邮箱服务有哪些&#xff1f;外贸公司邮箱申请哪个好呢&#xff1f;常见的企业邮箱包括网易企业邮箱、TOM企业邮箱、腾讯企业邮箱等。企业邮箱登录入口&#xff1a;好用的企业邮箱功…

把接口调用打成jar包的类怎么写_如何实时主动监控你的网站接口是否挂掉并及时报警...

“ 阅读本文大概需要 10 分钟。 ”最近我在公司负责的业务已经正式投入上线了&#xff0c;既然是线上环境&#xff0c;那么就需要保证其可用性。我负责的业务其中就包括一个 Web Service&#xff0c;我需要保证 Service 的每个接口都是可用的&#xff0c;如果某个时间流量大了或…

php织梦导航被选中,PHP网站分类目录程序 网址导航程序 织梦二次开发

织梦二次开发的PHP网站分类目录程序介绍&#xff1a;现在网络上很多的网站分类目录都是ASP格式&#xff0c;唯一一个PHP的程序因为文章功能和可扩展性太弱&#xff0c;小菜考虑到自己一个网站运营需要类似程序&#xff0c;而考虑到织梦程序的大众性和易优化性&#xff0c;就花2…

通州网站服务器,用光明为黄城根小学通州校区照亮希望

2019年8月1日&#xff0c;由北京住总集团承建的北京城市副中心职工周转房北区二标六号地块即黄城根小学通州校区&#xff0c;顺利通过五方验收&#xff0c;确保了九月入学条件。黄城根小学通州校区位于城市副中心职工周转房北区院内&#xff0c;是按照北京城市副中心整体规划部…

vue第一次加载慢怎么优化_Vue 网站首页加载优化

Vue 网站首页加载优化本篇主要讲解 Vue项目打包后 vendor.js 文件很大 如何对它进行优化 以及开启Vue的压缩 和 nginx gzip 压缩的使用&#xff0c;其他就是对接口优化等1. vendor.js 优化由于Vue项目随着功能变多 依赖也会随之变多&#xff0c;减少vendor.js的主要方法就是将其…

win7 iis安装php mysql_WIN7下配置IIS7.5+PHP5.3+MySQL动态网站服务器环境

比APPPSERV傻瓜建站包操作更简便、更智能、更科学的建站方法声明&#xff1a;采用环境及各软件版本&#xff0c;以下软件均采用当前最新版1.操作系统Windows7 英文旗舰版&#xff0c;自带IIS7.5&#xff1b;2.PHP软件版本&#xff1a;php-5.3.2-nts-Win32-VC9-x86.msi&#xff…

thinkphp5项目--企业单车网站(三)

thinkphp5项目--企业单车网站&#xff08;三&#xff09; 项目地址 fry404006308/BicycleEnterpriseWebsite: Bicycle Enterprise Websitehttps://github.com/fry404006308/BicycleEnterpriseWebsite 一、动态查询 thinkphp支持动态查询&#xff0c;这就很方便了&#xff0c;可…

【网站前端】第02章 HTML常用标签

一、标题标签<h1> - <h6> &#xff08;重要&#xff09; 1、例&#xff1a;<h1> 我是一级标题 </h1> 2、语义&#xff1a;作为标题使用&#xff0c;并且依据重要性递减。 二、段落标签&#xff08;重要&#xff09; 1、例&#xff1a;<p> 我…

DotNetCore 结合 Nginx 将网站部署到阿里云

基础环境配置 域名和服务器请先自行购买 基于 云服务器ECS 创建一个应用实例&#xff0c;选择系统镜像为 Ubuntu 16.04&#xff0c;在本机通过 SSH 进行远程连接&#xff0c;并进行相关配置 ssh roothttp://39.108.48.203/...sudo apt-get update sudp apt-get upgrade sudo ap…