[转载]web地图信息格网索引-----基于google map api和oracle查询的生活地图

[转载]web地图信息格网索引—–基于google map api和oracle查询的生活地图 – 梦开始的地方 – 博客园.

当前项目中的优惠促销信息需要和地图位置相关起来,所以就用到了google map。根据需求,要做一个在地图上显示郑州地区所有优惠促销信息的页面。首先对这个需求进行了分析,郑 州的优惠促销信息是非常多的,如何在地图上将所有的信息显示出来?如果全部显示出来,将会出现信息的压盖和信息将地图压盖起来,用户看不到地图,也看不清 楚信息。所以就需要一定的处理。

网上通行的做法就是对地图上显示的信息进行分页展示,这样在页面上显示的信息就不会很多,用可以很 清晰的看到地图和地图上所展示的信息。如google map

其它的都是同样的方式,只是显示的样式有所不同。

Google map还提供了另一种方式,

将所有的信息都呈现在地图上,google map所呈现的所有信息点是绘制在图片上的,也就是说,google map的开发人员利用api有开发和制作了一个图层,和影像、纹理是同一级别的图片索引集合,数据传送到本地浏览器,这样数据不 用做显示,提高了浏览器的速度,也完成了信息的查询。如果利用google map提供的marker来做,显然数据量是非常巨大的,浏览器无法 承受如此多的marker对象的绘制。所以google map才用了静态图片来实现。

我们也想在地图上显示所有的数据,但是我们没有google那么强大的实力,说以就仿照了google 高考2009地图:

将信息聚合显示在地图之上,也就是说在某一位置,告诉用户这个地方有多少优惠促销信息,你可以放大或 点击进入进行查看。

目标有了之后就开始研究如何实现。我的测试数据是100万条优惠促销信息。

初始实现方法:根据查询,将所有符合条件的数据读取出来,通过ajax发送到前台,然后在前台进行相交压盖判断。

试验结果是一次读取的数据量太大,消耗太多的时间,另一个就是数据读取完成之后发送到前台占用大量的带宽。再有就是前台浏览器运算压盖消耗太多 的时间。

经过试验,不可行,需要进行改进,不过流程上没有太大的问题。所以感觉的思路如下:

1、 减少数据库中读取出来的数据进行。

2、 在前台建立格网索引,加快计算压盖速度。

经过分析,如果减少数 据库读取出来的数据,那就没有在地图上显示或提示出网站所有的优惠促销信息,在前台建立格网索引,依然需要将大量的数据传送到前台,那为什么不在后台建立 格网索引呢。分析过后,将格网索引放在后台进行处理。经过改进,是比第一次有所提高,但还不够。

经过一系列的试验分析思考之后, 得出了解决方案。

将格网索引放置在数据库中,一个查询就可聚合分组查询出所以优惠促销。减少数据的读取和网络间的传 送,简化前台开发(oracle 有支持地理实体的组件,Oracle Spatial,但是对于这个需求并不实用)

具体方法如下:

1、 google map区域的建立格网

因为google map的缩放分级,所以,建立格网时需要根据不同的级别进行创建。当前所做的指真对郑州地图,所以格网重12级到19级。如 图:

12级为16*16的 格网

13级为32*32的 格网

….

格网的递增为四叉树。因为从12级开始就需要显示丰富的信息,说以第一级不是一个2*2的网 格,而是一个15*15的网格。

格网个2维的数组,将其转换为1维数组,即12级格网号顺序从1开始到256结束。 第一排从116,第二排从17-32以 次类推,最终完成格网的模型创建。

下边开始对数据库进行设计。

创建数据表。

字段

类型描述

信息id

关联的信息id

Lev12

整型格网号

Lev13

整型格网号

Lev14

整型格网号

Lev15

整型格网号

Lev16

整型格网号

Lev17

整型格网号

Lev18

整型格网号

Lev19

整型格网号

通过计算,将二维的点状信息转换为相应级别下的格网好

insert into shopindex (shopid) values (sid);

更新索引

update shopindex s

set (lev12, lev13, lev14, lev15, lev16, lev17, lev18, lev19) = (select GetGirdNo(px,

py,

1212) lev12,

GetGirdNo(px,

py,

1312) lev13,

GetGirdNo(px,

py,

1412) lev14,

GetGirdNo(px,

py,

1512) lev15,

GetGirdNo(px,

py,

1612) lev16,

GetGirdNo(px,

py,

1712) lev17,

GetGirdNo(px,

py,

1812) lev18,

GetGirdNo(px,

py,

1912) lev19

from ooshop f

where s.shopid = f.id)

where s.shopid = sid;

根据xylev获取格网号 函数

create or replace function GETGIRDNO(x in integer,

y in integer,

lev in integer)

return integer is

girdnum INT := 15;

width INT := 110866;

height INT := 77900;

gnum INT;

stpwidth int;

stpheight int;

xmin int := 40869800;

ymin int := 12467548;

col int;

row int;

res int;

BEGIN

gnum := girdnum * POWER(2, lev);

stpwidth := width / gnum;

stpheight := height / gnum;

col := (x – xmin) / stpwidth;

row := (y – ymin) / stpheight;

res := col + row * gnum;

if res < 0 or res >girdnum*girdnum * POWER(4, lev) then

res := 0;

end if;

return res;

END GetGirdNo;

信息如图

有了这个索引表之后,就可以用oracle的分组查询,一个查询将给定范围的数据进行分组查询出来,分组的依据就个格网,这样查询出的数据就是 在这个格网下有多少条优惠促销信息。

获取12级的分组数据

select lev12,count(shopid) from shopindex t group by lev12


真正的查询要比这复杂点,要根据给定的地图范围进行查询,这样就需要一个函数,即根据地图范围获取这个范围下的所有格网。函数如下:

create or replace function GETGIRDNOS(stcol in integer,

strow in integer,

encol in integer,

enrow in integer,

lev   in integer)

RETURN colrows IS

gnum    int;

i       int;

j       int;

girdnum INT := 15;

colrow  colrows := colrows();

BEGIN

i := strow;


gnum := girdnum * POWER(2, lev);

while (i <= enrow) loop

j := stcol;

while (j <= encol) loop

colrow.EXTEND;

colrow(colrow.COUNT) := j + i * gnum;

j := j + 1;

end loop;

i := i + 1;

end loop;

RETURN colrow;

END GetGirdNos;

数 据的读取

var result = new Collection<ooBFeature>();

while (reader.Read())

{

ooBFeature gm = new ooBFeature(1);

gm.I = reader.GetInt32(0);

gm.N = reader.GetValue(1).ToString();

int row = (int)(gm.I / grid.GNum);

int col = (int)(gm.I % grid.GNum);

gm.X = col * grid.StpWidth + grid.StpWidth / 2 + ooGridModel.x;

gm.Y = row * grid.StpHeight + grid.StpHeight / 2 + ooGridModel.y;

result.Add(gm);

}

return result;

根据读取出的格网计算出地 图上的坐标。以上就是用oracle建立地理信息索引的方法,如有问题, 可进行交流。

效果页面http://www.map85.com/map

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏