【GIS】postgres(postgis) --》nodejs+express --》geojson --》leaflet
一、基本架构
1、数据存储层:PostgreSQL-9.2.13 + postgis_2_0_pg92
2、业务处理层:Nodejs + Express + PG驱动
3、前端展示层:Leaflet
二、参考资料
1、POSTGIS 函数接口:
https://blog.csdn.net/pzysoft/article/details/76944160
2、POSTGIS官方文档:
http://www.postgres.cn/index.php/home
http://postgis.net/docs/manual-2.3/ST_AsGeoJSON.html
http://www.postgres.cn/
3、NODEJS+POSTGRES:
http://yijiebuyi.com/blog/d70c54b7de06d6151b3c68b1474e4bf8.html
https://blog.csdn.net/wan_yanyan528/article/details/49250717
https://blog.csdn.net/cheneypao/article/details/51378053
三、关键代码
1、geojson处理:GeoJsonUtil.js
function ToGeoJson(jsonObject) {
//移除geometry
//把其他属性变为properties
var geoJson = {
"type": "Feature"
};
// console.log(jsonObject)
// console.log(jsonObject.geometry)
geoJson.geometry = eval('(' + jsonObject.geometry + ')');
delete jsonObject.geometry;
// console.log(jsonObject)
geoJson.properties = jsonObject;
return geoJson;
}
exports.ToGeoJson = ToGeoJson;
2、PG访问:pg.js
var pg = require('pg');
var server = 'localhost'
var db = 'ecodb'
var user = 'postgres'
var pwd = '*******'
var port = '5432'
var conString = "tcp://" + user + ":" + pwd + "@" + server + "/" + db + "";
var pgConfig = {
user: user,
database: db,
password: pwd,
host: server,
port: port,
poolSize: 5,
poolIdleTimeout: 30000,
reapIntervalMillis: 10000
};
var pgPool = new pg.Pool(pgConfig);
var client = new pg.Client(conString);
var PG = function () {
console.log("准备向****数据库连接...");
};
PG.prototype.getConnection = function () {
client.connect(function (err) {
if (err) {
return console.error('could not connect to postgres', err);
}
client.query('set client_encoding to "utf8";SELECT NOW() AS "theTime"', function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log(db + "数据库连接成功...");
});
});
};
// 查询函数
//@param str 查询语句
//@param value 相关值
//@param cb 回调函数
var clientHelper = function (str, value, cb) {
client.query(str, value, function (err, result) {
if (err) {
cb("err");
console.log(err);
} else {
// console.log(result)
if (result.rows != undefined)
cb(result.rows);
else
cb();
}
});
}
PG.prototype.exec = function (strSql, cb) {
client.query(strSql, "", function (err, result) {
if (err) {
cb("err");
console.log(err);
} else {
// console.log(result)
if (result.rows != undefined)
cb(result.rows);
else
cb();
}
});
}
//增
//@param tablename 数据表名称
//@param fields 更新的字段和值,json格式
//@param cb 回调函数
PG.prototype.save = function (tablename, fields, cb) {
if (!tablename) return;
var str = "insert into " + tablename + "(";
var field = [];
var value = [];
var num = [];
var count = 0;
for (var i in fields) {
count++;
field.push(i);
value.push(fields[i]);
num.push("$" + count);
}
str += field.join(",") + ") values(" + num.join(",") + ")";
clientHelper(str, value, cb);
};
//删除
//@param tablename 数据表名称
//@param fields 条件字段和值,json格式
//@param cb 回调函数
PG.prototype.remove = function (tablename, fields, cb) {
if (!tablename) return;
var str = "delete from " + tablename + " where ";
var field = [];
var value = [];
var count = 0;
for (var i in fields) {
count++;
field.push(i + "=$" + count);
value.push(fields[i]);
}
str += field.join(" and ");
clientHelper(str, value, cb);
}
//修改
//@param tablename 数据表名称
//@param fields 更新的字段和值,json格式
//@param mainfields 条件字段和值,json格式
PG.prototype.update = function (tablename, mainfields, fields, cb) {
if (!tablename) return;
var str = "update " + tablename + " set ";
var field = [];
var value = [];
var count = 0;
for (var i in fields) {
count++;
field.push(i + "=$" + count);
value.push(fields[i]);
}
str += field.join(",") + " where ";
field = [];
for (var j in mainfields) {
count++;
field.push(j + "=$" + count);
value.push(mainfields[j]);
}
str += field.join(" and ");
clientHelper(str, value, cb);
}
//查询
//@param tablename 数据表名称
//@param fields 条件字段和值,json格式
//@param returnfields 返回字段,字段数组
//@param cb 回调函数
PG.prototype.select = function (tablename, fields, returnfields, cb) {
if (!tablename) return;
var returnStr = "";
console.log(returnfields)
if (returnfields.length == 0)
returnStr = '*';
else
returnStr = returnfields.join(",");
var str = "select " + returnStr + " from " + tablename; // + " where ";
console.log('select:' + str)
var field = [];
var value = [];
var count = 0;
if (fields != '') {
for (var i in fields) {
count++;
field.push(i + "='" + fields[i] + "'");
value.push(fields[i]);
}
}
if (count != 0) {
str += " where " + field.join(" and ");
}
console.log('select:' + str)
clientHelper(str, value, cb);
};
module.exports = new PG();
3、geojson服务:pgclient.js
var pgclient = require('./PG')
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var geoJson = require('./GeoJsonUtil')
//访问端口
var port = 9999
//接受post数据
app.use(bodyParser.urlencoded({
extended: false
}));
//初始化数据库连接
pgclient.getConnection();
//设置跨域
function setCross(res) {
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
//允许的header类型
res.header("Access-Control-Allow-Headers", "content-type");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
}
//数据记录转换为GeoJson
function DataToGeoJson(ds) {
var jsonDS = JSON.stringify(ds);
var geojson = {
"type": "FeatureCollection"
}
var features = [];
jsonDS = eval('(' + jsonDS + ')')
for (var p in jsonDS) {
var PO = jsonDS[p]
var pRet = geoJson.ToGeoJson(PO);
features.push(pRet)
}
geojson.features = features;
return geojson;
}
app.get('/ListSTSAreaJson2', function (req, res) {
console.log(req.query)
console.log(req.body)
setCross(res)
var sql = "select id,name,code,color,show_on_map,ST_AsGeoJson(shape,6) as geometry from chinastsarea ";
var strSql = req.query.code == undefined ? sql :
sql + " where code='" + req.query.code + "'";
pgclient.exec(strSql, function (ds) {
// console.log(ds)
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf-8'
});
try {
var geojson = DataToGeoJson(ds)
res.end(JSON.stringify(geojson));
} catch (error) {
}
})
})
5、Leaflet空间数据展示:leaflet.geojson.html
<html> <head>
<meta charset=utf-8 />
<title>Leaflet Control.Layers</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <!-- Load Leaflet from CDN -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA=="
crossorigin=""></script> <!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet@2.2.3/dist/esri-leaflet.js" integrity="sha512-YZ6b5bXRVwipfqul5krehD9qlbJzc6KOGXYsDjU9HHXW2gK57xmWl2gU6nAegiErAqFXhygKIsWPKbjLPXVb2g=="
crossorigin=""></script> <script src='../assets/libs/jquery/jquery-2.1.1.min.js'></script> <style>
body {
margin: 0;
padding: 0;
} #map {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>
<style>
#selectedFeatures {
position: absolute;
bottom: 180px;
right: 10px;
z-index: 1000;
background: white;
padding: 1em;
} #selectedFeatures2 {
position: absolute;
bottom: 240px;
right: 10px;
z-index: 1000;
background: white;
padding: 1em;
} .leaflet-bar.map-text a {
color: #79BD8F;
display: inline;
}
</style>
<style>
#time-ranges {
position: absolute;
bottom: 300px;
right: 10px;
z-index: 1000;
padding: 1em;
background: white;
} #time-ranges input {
display: inline-block;
border: 1px solid #999;
font-size: 14px;
border-radius: 4px;
height: 28px;
line-height: 28px;
} #time-ranges input[type='submit'] {
box-sizing: content-box;
padding: 0 1em;
text-transform: uppercase;
color: white;
background: #5C7DB8;
border-color: #5C7DB8;
}
</style>
</head> <body> <div id="map"></div> <script>
var gray = L.layerGroup(); // more than one service can be grouped together and passed to the control together
L.esri.basemapLayer("DarkGray").addTo(gray);
L.esri.basemapLayer("GrayLabels").addTo(gray); var map = L.map('map', {
zoom: 4,
layers: [gray]
}); var stsAreaLayer, stsSTSChildAreaLayer, stsSTSDemoAreaLayer; $.ajax({
dataType: "json",
url: "http://192.168.198.21:9999/ListSTSAreaJson2",
success: function (data) { console.log(data); stsAreaLayer = L.geoJSON(data).addTo(map);
}
}).error(function () {}); $.ajax({
dataType: "json",
url: "http://192.168.198.21:9999/ListSTSChildAreaJson2",
success: function (data) { console.log(data); stsSTSChildAreaLayer = L.geoJSON(data).addTo(map);
}
}).error(function () {}); $.ajax({
dataType: "json",
url: "http://192.168.198.21:9999/ListSTSDemoAreaJson2",
success: function (data) { console.log(data); stsSTSDemoAreaLayer = L.geoJSON(data).addTo(map);
}
}).error(function () {}); map.setView([37.71, 109.88], 3);
</script> </body> </html>
【GIS】postgres(postgis) --》nodejs+express --》geojson --》leaflet的更多相关文章
- NoSQL之【MongoDB】学习(三):配置文件说明
摘要: 继上一篇NoSQL之[MongoDB]学习(一):安装说明 之后,知道了如何安装和启动MongoDB,现在对启动时指定的配置文件(mongodb.conf)进行说明,详情请见官方. 启动Mon ...
- 【操作系统】进程间通信(C#)
原文:[操作系统]进程间通信(C#) 08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活.此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xia ...
- 【Luogu3444】ORK-Ploughing(贪心)
[Luogu3444]ORK-Ploughing(贪心) 题面 Luogu 题解 我们知道,如果我们选定了以横向为主,或者纵向为主, 那么就有尽可能减少另一个方向上耕地的次数 所以分开贪心,但是本质相 ...
- 【BZOJ1997】Planar(2-sat)
[BZOJ1997]Planar(2-sat) 题面 BZOJ 题解 很久没做过\(2-sat\)了 今天一见,很果断的就来切 这题不难呀 但是有个玄学问题: 平面图的性质:边数\(m\)的最大值为\ ...
- 【Luogu1337】平衡点(模拟退火)
[Luogu1337]平衡点(模拟退火) 题面 洛谷 题解 和BZOJ3680吊打XXX是一样的.. 但是数据很强呀.. 疯狂调参 各种WA... 很无奈呀.... #include<iostr ...
- 【BZOJ1996】合唱队(动态规划)
[BZOJ1996]合唱队(动态规划) 题面 BZOJ 题解 很容易的一道题 因为每个人不是放在了左边就是放在了右边 所以每次放好的人必定是原序列的一个子串 所以,很容易想到区间\(dp\) 设\(f ...
- 【BZOJ1899】午餐(动态规划)
[BZOJ1899]午餐(动态规划) 题面 BZOJ 题解 我太弱了 这种\(dp\)完全做不动.. 首先,感性理解一些 如果所有人都要早点走, 那么,吃饭时间长的就先吃 吃饭时间短的就晚点吃 所以, ...
- 【BZOJ1040】骑士(动态规划)
[BZOJ1040]骑士(动态规划) 题面 BZOJ 题解 对于每一组厌恶的关系 显然是连边操作 如果是一棵树的话 很显然的树型\(dp\) 但是,现在相当于有很多个基环 也就是在一棵树的基础上再加了 ...
- 【BZOJ3527】力(FFT)
[BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...
随机推荐
- node学习笔记2——搭建服务器
搭建服务器关键词: require('http') —— 请求 node 里面的 http 模块 createServer —— 创建一个服务器 request —— 请求 response—— 响应 ...
- 【Qt开发】QThread 实用技巧、误区----但文档中没有提到
本文主要内容: 在任务一中,用 四 种方式实现:点击界面按钮,开线程运行一段程序,结果显示在一个Label上.1. 用不正确的方式得到看似正确的结果2. 用Qt Manual 和 例子中使用的方法3. ...
- 实验三 使用ASP.NET常用服务器控件 总结
这次实验内容是服务器控件的使用,大部分控件都是来自VS2008中的工具箱.使用的时候视图切换到设计或者分析,把工具箱中的目标控件直接拖拽到想要的位置.使用起来非常方便,而且可以通过直接点击控件来对它的 ...
- 权限控制-JS判断是否有权限进行操作跳转页面需要加target
妈蛋的,这问题花了我20分钟,我用来搜索代码花了18分钟,我写代码有个差生的习惯,就是抄,啥东西想做,就上网搜别人杂写,拿下来照抄改一下即可 啧啧,妈蛋的,整个一页,没有我能用到的信息,那些博客内容一 ...
- 第三百四十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—craw母版l创建自动爬虫文件—以及 scrapy item loader机制
第三百四十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—craw母版l创建自动爬虫文件—以及 scrapy item loader机制 用命令创建自动爬虫文件 创建爬虫文件是根据scrap ...
- Java如何获取正在运行的线程的名称?
在Java编程中,如何获取正在运行的线程的名称? 以下示例显示如何获取正在运行的线程的名称. package com.yiibai; public class GettingThreadName ex ...
- 高校区LAN局域网校内网组建实践经验
项目描述: ●校区计算机网络组建与管理和维护. 主要内容: 1.电脑故障诊断与排除与维护. 2.修复局域网内的故障电脑. 3.局域网架设虚拟系统. 4.局域网升级. 5.局域网基础架构. 6.电脑系统 ...
- unity----------------------四元数的概念
作者:Yang Eninala链接:https://www.zhihu.com/question/23005815/answer/33971127来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...
- C# 抓取并导出网页里面所有超链接方法
public class app { // 获取指定网页的HTML代码 public static string GetPageSource(string URL) { Uri uri = new U ...
- Maven最佳实践-distributionManagement
分发构件至远程仓库 mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库.本地Maven仓库的构件只能供当前用户使用, ...