热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:PostGIS计算矢量切片唯一值渲染

本文由编程笔记#小编为大家整理,主要介绍了PostGIS计算矢量切片--唯一值渲染相关的知识,希望对你有一定的参考价值。????没写错,是使用postgis计算出来矢量切片。在
本文由编程笔记#小编为大家整理,主要介绍了PostGIS计算矢量切片--唯一值渲染相关的知识,希望对你有一定的参考价值。


????没写错,是使用postgis计算出来矢量切片。在这之前先准备一个数据:一个GIS数据表(本例中数据为一百万的点数据,坐标:4326),并在表中添加x,y字段,方便后面的数据筛选。sql中用到了
ST_AsMVT和ST_AsMVTGeom。
????本文中创建矢量切片很简单,就是使用下方的一个sql,运行结果如下图。接着写一个矢量切片的http服务(参考go-vtile-example,这个例子中矢量切片压缩率更高),并且使用mapbox进行前端展示(小贴士:sql中‘points’的字符串与渲染中mapbox里的source-layer一致).代码见最下方

SELECT ST_AsMVT(tile,‘points‘) tile FROM(
SELECT ST_AsMVTGeom(geom,ST_MakeEnvelope(100,10,125,22, 4326),4096, 0, true)
AS geom FROM grid20180322 )
AS tile where tile.geom is not null

技术分享图片

技术分享图片
技术分享图片
技术分享图片

package main
import
(
_ "github.com/lib/pq"
"database/sql"
"time"
"log"
"math"
"errors"
"fmt"
"net/http"
"regexp"
"strconv"
"strings"
)
func tilePathToXYZ(path string) (TileID, error) {
xyzReg := regexp.MustCompile("(?P[0-9]+)/(?P[0-9]+)/(?P[0-9]+)")
matches := xyzReg.FindStringSubmatch(path)
if len(matches) == 0 {
return TileID{}, errors.New("Unable to parse path as tile")
}
x, err := strconv.ParseUint(matches[2], 10, 32)
if err != nil {
return TileID{}, err
}
y, err := strconv.ParseUint(matches[3], 10, 32)
if err != nil {
return TileID{}, err
}
z, err := strconv.ParseUint(matches[1], 10, 32)
if err != nil {
return TileID{}, err
}
return TileID{x: uint32(x), y: uint32(y), z: uint32(z)}, nil
}
type LngLat struct {
lng float64
lat float64
}
type TileID struct {
x uint32
y uint32
z uint32
}
func tile2lon( x int, z int)(a float64) {
return float64(x) /math.Pow(2, float64(z)) * 360.0 - 180;
}
func tile2lat( y int, z int)(a float64) {
n := math.Pi - (2.0 * math.Pi * float64(y)) / math.Pow(2, float64(z));
return math.Atan(math.Sinh(n))*180/math.Pi;
}

func FloatToString(input_num float64) string {
// to convert a float number to a string
return strconv.FormatFloat(input_num, ‘f‘, 6, 64)
}
func loadData(xyz TileID)(a []byte){
ymax :=FloatToString(tile2lat(int(xyz.y), int(xyz.z)));
ymin := FloatToString(tile2lat(int(xyz.y+1), int(xyz.z)));
xmin := FloatToString(tile2lon(int(xyz.x), int(xyz.z)));
xmax := FloatToString(tile2lon(int(xyz.x+1), int(xyz.z)));
fmt.Println("ymax: ", ymax)
fmt.Println("ymin: ",ymin)
fmt.Println("xmin : ",xmin )
fmt.Println("xmax : ",xmax )
connStr := "dbname=xx user=xx password=xx host=localhost port=5433 sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
panic(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
var tile []byte
s := []string{xmin,ymin,xmax,ymax}
maxmin:=strings.Join(s, ",")
s2 := []string{" where (x between", xmin,"and",xmax,") and ( y between",ymin,"and",ymax,")"}
wmaxmin:=strings.Join(s2, " ")
sql:="SELECT ST_AsMVT(tile,‘points‘) tile FROM(SELECT ST_AsMVTGeom(w.geom,ST_MakeEnvelope("+maxmin+", 4326),4096, 0, true) AS geom FROM (select geom from grid20180322"+wmaxmin+") w) AS tile where tile.geom is not null"
rows1:= db.QueryRow(sql)
err1 := rows1.Scan(&tile)
if err1 != nil {
log.Fatal(err1)
}
fmt.Println(sql)
//defer rows1.Close()
return tile
}
func main(){
//t1 := time.Now()
mux := http.NewServeMux()
tileBase := "/tiles/"
mux.HandleFunc(tileBase, func(w http.ResponseWriter, r *http.Request) {
t2 := time.Now()
log.Printf("url: %s", r.URL.Path)
tilePart := r.URL.Path[len(tileBase):]
fmt.Println("tilePart: ", tilePart)
xyz, err := tilePathToXYZ(tilePart)
fmt.Println("xyz: ", xyz)

if err != nil {
http.Error(w, "Invalid tile url", 400)
return
}
tile:=loadData(xyz)

// All this APi to be requests from other domains.
w.Header().Set("Content-Type", "application/x-protobuf")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Write(tile)
elapsed2 := time.Since(t2)

fmt.Println("耗时: ", elapsed2)
})
log.Fatal(http.ListenAndServe(":8081", mux))
}

html>



















推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有